了解C++默默编写并调用哪些函数

在C++中,如果你写下

1 classEmpty{…};

 

就相当于写下
1 classEmpty{
2 public:
3 Empty();//default构造函数
4 Empty(constEmpty& rhs){……};//copy构造函数
5 ~Empty(){…}//析构函数
6 Empty&operator=(constEmpty& rhs){…};//copy赋值运算符
7 };

 

    惟有当这些函数被调用时,他们才会被编译器创建出来。
    下面代码造成上述每个函数被创建:
1 Empty e1;        //default构造函数
2 Empty e2(e1);    //析构函数
3 e2=e1;           //copy构造函数,copy赋值运算符
 
 
  如果你设计了一个class,其构造函数要求有实参,你就无需担心编译器会为你添加一个无实参版本而覆盖掉你的版本
 1 template<typename T>
 2 classNamedObject{
 3 public:
 4 NameObject(constchar* name,const T& value);
 5 NameObject(const std::string& name,const T& value);
 6 private:
 7 std::string nameValue;
 8 T objectValue;
 9 };
10 NamedObject<int> no1("Smallest Prime Number",2);
11 NamedObject<int> no2(no1);//调用copy构造函数

 

 

        编译器为NamedObject<int>所生成的copy赋值运算符,其行为基本上与copy构造函数如出一辙,但一般而言只有在生出的代码合法且有合适机会证明它有意义,其表现才会如先前所说。万一条件不符,编译器会拒绝为其生出operator=。
 
例如:
1 template<typename T>
2 classNamedObject{
3 public:
4 NamedObject(std::string& name,const T& value);
5 private:
6 std::string& nameValue;
7 const T objectValue;
8 };

 

 

 
 
 
  
 
考虑下面会发生什么:
 
1 std::string newdog("Persephone");
2 std::string olddog("Satch");
3 NamedObject<int> p(newdog,2);
4 NamedObject<int> s(olddog,36);
5 p=s;                        //现在p要发生什么事?

 

赋值前,p.nameValue和s.nameValue都指向string对象。p该如何变化?是reference改变吗?C++不允许让 reference改指向不同的对象。是string对象被修改吗?那么将影响其他持有指针或引用而且指向该string的其他对象。对此,C++拒绝编译那一行赋值动作。

 
最后还有一种情况:    如果某个基类将copy赋值运算符声明为private,编译器将拒绝为其派生类生成copy赋值运算符。
毕竟编译器为派生类所生的copy赋值运算符想象中可以处理基类成分,但他们当然无法调用派生类无法调用的函数。

而如果你不想使用这些自动生成的成员函数,可以在private成员里面声明他们,而不提供定义。

1 class HomeForSale{
2 public:
3     ……
4 private:
5     HomeForSale(const HomeForSale);
6     HomeForSale& operator=(const HomeForSale);
7 };

 

有了上述class定义,当用户企图拷贝HomeForSale对象,编译器会阻挠他,如果你不慎在member函数或friend函数内那么做,轮到链接器发出抱怨。

  将链接期错误移至编译期是可能的(而且那是好事,毕竟愈早发现错误愈好),只要将copy构造函数和copy赋值运算符声明为private就可以办到,但不是HomeForSale自身,而是在一个专门为了阻止copying动作而设计的base class非常简单。

1 class Uncopyable{
2 protected:
3     Uncopyable() {}          //允许derived对象构造和析构
4     ~Uncopyable(){}
5 private:
6     Uncopyable(const Uncopyable&);          //但阻止copying
7     Uncopyable& operator=(const Uncopyable&);      
8 };

 

 

 
 


参考资料:《Effective C++》



转载于:https://www.cnblogs.com/Lighters-c/p/6060322.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值