C++ 构造函数浅析

1、C++ 构造函数分类

  C++中分为默认构造函数、拷贝构造函数、赋值函数、自定义构造函数。

  举例如下:

  当类中没有构造函数时,编译器会为此类生成默认构造函数并在生成对象时自动调用。

 
  自定义构造函数:
         USER_T()
         {
           printf(" 普通构造函数\n");
         }
        USER_T(intid,string name,int sockValue)
       :index(id),nodeName(name)
        {
            sock.fd= sockValue;
            printf(" 自定义构造函数\n");
        }
  赋值函数:

        USER_T&operator=(const USER_T& user)
        {
           printf("赋值构造函数\n");
           index=user.index;
           nodeName=user.nodeName;
           sock=user.sock;
        }
     拷贝构造函数:

     USER_T(const USER_T& user)
        {
          printf("拷贝构造函数\n");
          index=user.index;
          nodeName=user.nodeName;
          sock=user.sock;
        }

2、各种类型构造函数使用情景
自定义构造函数:

   定义对象时、以new方式生成对象指针时

  拷贝构造函数:

    当函数参数为对象传参数时、当返回为对象时、用已有对象初始化对象时

  赋值函数:

   显示使用==对象赋值时

 3、验证

#include <stdlib.h>
#include <stdio.h>
#include <string>
using namespace std;

typedef struct SOCK
{
    int fd;
}SOCK_T;

class USER_T
{
    public:
        USER_T()
        {
           printf(" 普通构造函数\n");
         }
        USER_T(intid,string name,int sockValue)
           :index(id),nodeName(name)
        {
            sock.fd= sockValue;
            printf(" 自定义构造函数\n");
        }
       USER_T(const USER_T& user)
        {
         printf("拷贝构造函数\n");
         index=user.index;
         nodeName=user.nodeName;
         sock=user.sock;
        }
     USER_T& operator=(const USER_T& user)
        {
           printf("赋值构造函数\n");
           index=user.index;
           nodeName=user.nodeName;
           sock=user.sock;
        }
        void show()
        {
           printf("USER_T:index[%d] name[%s]fd[%d]\n",index,nodeName.c_str(),sock.fd);
        }
private:
    int index;
    stringnodeName;
    SOCK_T sock;
};
USER_T getUser();
void display(USER_T user)
{
    user.show();
    printf("Eixt display()\n");
}

int main ( int argc, char *argv[] )
{
    USER_T user;
    printf("user address:%d\n",&user);
    user=getUser();
    printf("****read to display()****\n");
    display(user);
    printf("****test NRVO****\n");
    USER_TuserNrvo=getUser();
    printf("userNrvo address:%d\n",&userNrvo);
   printf("****test NRVO end****\n");
    getchar();
    returnEXIT_SUCCESS;
}               /*----------  end of function main  ---------- */
USER_T getUser()
{
   printf("Enter getuser()\n");
    USER_T user1;
   printf("geruser:return user address[%d]\n",&user1);
    USER_T* pUser =new USER_T(1212,"KK",890);
    printf("new User finished\n");
    user1=*pUser;
    delete pUser;
   .printf("Exit getuser()\n");
    return user1;
}

执行结果如下:

 

值得注意的是g++ 默认采用RVO优化,导致当对象为返回值时应该调用的拷贝构造函数执行被优化省略了。

4、延深思考-何时需要自定义拷贝构造函数

   Q:

     对于拷贝构造函数,为了防止浅拷贝造成的两个对象指向同一内存,当删除其中一个对象后导致另一对象指向内容为空的时候,我们就需要定义自己的拷贝构造函数来进行深拷贝。

对于自定义结构当结构成员中没有需要动态分配的指针成员时,完全不需要自定义拷贝构造函数。

如:

 struct USER_T

{

   Int index;

   String name;

   SOCK sock;

};

执行newUser=oldUser; 时每个成员字段都会正确赋值即编译器默认会对每个字段执行浅拷贝。
    

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值