C++构造函数

1、复制构造函数

如果代码中没有为某个类定义复制构造函数,那么编译器就会隐式声明一个拷贝构造函数。比如下面的constructor.cpp中的Point类,我并没有创建Point(Point& p)形式的构造函数,但是Point b(a)却可以成功。

#include <stdio.h>
#include <string>
using std::string;
class Point{
public:
    Point(int x_value,int& y_value, const string& description_value):x(x_value),y(y_value),description(description_value){
    }//初始化列表

    string getDescription(){
        return description;
    }
    void setDescription(const string& description_value){
        description=description_value;
    }

    int getX(){
         return x;
     }

    void setX(int x_value){
          x=x_value;
        //  printf("x=%d,x_value=%d\n",x,x_value);
    }
    int getY(){
        return y;
    }
    void setY(int& y_value){
        y=y_value;
    }

private:
    int x,&y;
    string description;
};

int main(){
    int y1=2;
    string s1="this is a";
    Point a(1,y1,s1);
    Point b(a);//调用拷贝构造函数
    printf("a.x=%d,a.y=%d,a.description=%s\n",a.getX(),a.getY(),a.getDescription().c_str());
    printf("b.x=%d,b.y=%d,b.description=%s\n",b.getX(),b.getY(),b.getDescription().c_str());
    a.setX(3);
    int y2=3;
    string s2="this is a changed";
    a.setY(y2);
    a.setDescription(s2);
    printf("after alter,a.x=%d,a.y=%d,a.description=%s\n",a.getX(),a.getY(),a.getDescription().c_str());
    printf("after alter,b.x=%d,b.y=%d,b.description=%s\n",b.getX(),b.getY(),b.getDescription().c_str());

}

g++ constructor.cpp

./a.out

log打印如下:

a.x=1,a.y=2,a.description=this is a
b.x=1,b.y=2,b.description=this is a
after alter,a.x=3,a.y=3,a.description=this is a changed
after alter,b.x=1,b.y=3,b.description=this is a

值得注意的是当类的成员是const类型、引用类型、未提供默认构造函数的类类型时必须使用构造函数初始化列表,如果使用函数赋值的话会报error: uninitialized reference member。并且,初始化列表比先初始化再赋值的方式更加有效率。

2、移动构造函数

为了避免不必要的资源创建与释放,C++ 11中新增了移动资源而非拷贝创建资源的功能,对于将要消亡的源对象,将源对象所占资源通过右值引用的方式移动到目标对象中,从而避免销毁源对象资源以及为新对象开辟新空间放置资源,尤其对于占用内存大的对象

#include <stdio.h>
#include <string>
using std::string;
class Point{
public:
    Point(int& x_value,int y_value, const string& description_value):x(&x_value),y(y_value),description(description_value){
        printf("calling constructor...\n");
    }
    Point(Point &&p):x(p.x),y(p.y),description(p.description){
        p.x=nullptr;
        printf("calling move constructor...\n");
    }
    Point():x(new int(0)),y(0),description(""){
        printf("calling default constructor...\n");
    }
    Point(Point& p):x(p.x),y(p.y),description(p.description){
        printf("calling copy constructor...\n");
    }
    ~Point(){
        printf("calling destructor...\n");
    }
    int getY(){
        return y;
    }
private:
    int y;
    int* x;
    string description;
};
Point getPoint(){
      return Point();
}
int main(){
    printf("getY()=%d\n",getPoint().getY());
   // Point b(a);
    return 0;
}

g++ constructor.cpp -std=c++11 -fno-elide-constructors

./a.out

log打印如下:

calling default constructor...
calling move constructor...
calling destructor...
getY()=0
calling destructor...

3、委托构造函数

委托构造函数调用其他构造函数来完成构造细节,比如下面13行的无参构造函数去调用第6行的三个参数的构造函数从而完成成员变量的初始化。

#include <stdio.h>
#include <string>
using std::string;
class Point{
public:
    Point(int* x_value,int y_value, string description_value):x(x_value),y(y_value),description(description_value){
        printf("calling constructor...\n");
    }
    Point(Point &&p):x(p.x),y(p.y),description(p.description){
        p.x=nullptr;
        printf("calling move constructor...\n");
    }
    Point():Point(new int(0),0,"aaa"){
        printf("calling default constructor...\n");
    }
    ~Point(){
        printf("calling destructor...\n");
    }
    int getY(){
        return y;
    }
private:
    int y;
    int* x;
    string description;
};
Point getPoint(){
      return Point();
}
int main(){
    printf("getY()=%d\n",getPoint().getY());
   // Point b(a);
    return 0;
}

编译执行后log打印如下,可以看到先打印了三个参数的构造函数,再去打印无参构造函数

calling constructor...
calling default constructor...
calling move constructor...
calling destructor...
getY()=0
calling destructor...

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值