frankfan的胡思乱想

学海无涯,回头是岸

构造函数

普通构造 拷贝构造 隐式构造

构造函数

无论是普通的默认构造还是自定义参数构造函数,或者拷贝构造函数,都可以认为是对象创建完成后提供给用户的一个hook point.

给用户一个初始化对象成员的一个入口点,通常默认情况下编译器并不会自动实现默认构造函数,除非有成员变量的访问或者赋值等相关操作,而一旦用户实现了默认构造函数或者自定义了构造函数,那么在创建对象时则必须调用实现中的一个构造函数

对象创建成功后才会调用构造函数。

#include <iostream>
using namespace std;

class Node{
public:
  Node(){}
  Node(int v):value(v){}
private:
  int value;
};

int main(){
  Node node;//调用默认的构造函数
  Node node2(11);//调用带参构造函数
  //Node node3();并不会调用任何构造函数,这不过是函数的声明而已
}

用户在没有实现任何构造函数时,创建对象是编译器可能会(并不是一定会)调用默认实现的构造器函数,但是一旦用户实现了构造函数,则创建对象时,使用的构造器必须是已经实现的构造器中的一个

#include <iostream>
using namespace std;

class Node(){
public:
  Node(int v):value(v){}//实现了一个带参构造器
private:
  int value;
};

int main(){
  //❌
 	//Node node;编译报错,因为这是在使用无参构造函数创建对象,而在所有已实现的构造函数中并没有实现无参构造函数,因此无法使用默认无参构造函数创建对象
  return 0;
}

通常一个类并不只有一个构造函数,而是可能有多个构造函数,当有多个构造函数时,那么一个构造函数可以通过调用另一个构造函数实现定义

#include <iostream>
using namespace std;

class Node{
public:
  Node(){}
  Node(int v,char _id):value(v),id(_id){}
  Node(int v):Node(v,nullptr){}//通过另一个构造函数实现新的构造函数
  //但是不能写成这种方式
  /*
  Node(int v){
  	Node(v,nullptr)//这是在创建一个新的临时对象,并不是利用这个构造函数实现新的构造函数
  }*/
}
  ~Node(){}
private:
  int value;
  char *id;
};
int main(){
  Node node;
  Node node1(11);
  Node node2(12,"itemNode");
}

拷贝构造

除了直接创建对象,创建C++对象的另一种方式就是通过拷贝一个已经存在的对象创建出一个新的对象。

通过一个已存在的对象创建新对象时,即使并没有实现带参的拷贝构造函数,但是编译器依然会调用默认实现的拷贝构造完成对象的创建

#include <iostream>
using namespace std;

class Node(){
public:
  Node(int v = 0):value(v){}
  void showValue(){
    cout<<value<<endl;
  }
private:
  int value;
};
int main(){
  
  Node node(11);
  //并没有实现相关的带参构造函数,但是node2对象依然创建成功,这是因为编译器默认调用了拷贝构造函数,将对象node的内存拷贝到了node2的内存,这也是所谓的浅拷贝(只适合没有指针成员的类)
  Node node2(node);
  node.showValue();//11
  node2.showValue();//11
  return 0;
}

在发生拷贝构造时,若想不仅仅只实现对象与对象间单纯内存值的拷贝,同时也要将指针成员中指向的堆空间也拷贝,这就是所谓的深拷贝,那么需要实现拷贝构造函数

#include <iostream>
using namespace std;

class Node{
public:
  Node(){}
  Node(int bl,const char *bf){
    if(bl){
      buf_len = bl;
      buf = new char[buf_len+1];
      memcpy(buf,bf,buf_len+1);
    }
  }
  //自定义拷贝构造函数
  Node(const Node &node):Node(node.buf_len,node.buf){}
  
  ~Node(){
    if(buf != nullptr){
      delete[] buf;
      buf = nullptr;
    }
  }
private:
  int buf_len;
  char *buf;
};
int main(){
  
  char *str = "hello buf";
  Node node(strlen(str),str);
  Node node2(node);
  return 0;
}

隐式构造

在C++中,除了直接创建对象,通过拷贝构造创建对象外,还有一种隐式创建对象的方式

#include <iostream>
using namespace std;
class Node{
public:
  Node(int v = 0):value(v){}
  Node(const Node &node):value(node.value){}
  ~Node(){}
private:
  int value;
};
int main(){
  
  //从语法上看似乎有问题,但实际上这是C++中产生了隐式构造,调用了带参构造函数,创建了新的node对象,这种方式给理解带了了障碍。
  Node node = 12;
  return 0;
}

posted on 2021-12-28 00:27  shadow_fan  阅读(158)  评论(0编辑  收藏  举报

导航