了解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++》

时间: 2024-10-25 05:55:45

了解C++默默编写并调用哪些函数的相关文章

Effective C++ 之 Item 5:了解C++默默编写并调用哪些函数

Effective C++ chapter 2. 构造 / 析构 / 赋值运算 (Constructors, Destructors, and Assignment Operators) Item 5. 了解 C++ 默默编写并调用哪些函数 (Know what functions C++ silently writes and calls)

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

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验: 如果你自己没声明,编译器会自动声明copy constructor,copy assignment,destructor, 如果你没有声明任何构造函数,编译器会自动声明default constructor 示例: 如果你写下 class Empty{ }; 将会等价于 class Empty{ public: Empty() {...} //default构造函数 Empty(c

EC笔记,第二部分:5.了解C++默默编写并调用哪些函数

5.了解C++默默编写并调用哪些函数 1.C++空类 C++会为一个空类建立以下函数 (1).默认构造函数 (2).默认拷贝构造函数 (3).析构函数 (4).赋值运算符(如果成员包含引用类型或const类型,不会生成赋值运算符)(引用的对象和const对象不可更改,所以无法重新赋值) class cl1 { public: int a; cl1(int t):a(t) {}; }; class cl2 { public: int &a; cl2(int t):a(t) {} }; int ma

[effictive c++]条款05 了解c++默默编写并调用哪些函数

c++的编译器是非常智能的!当你声明一个空类empty class,如果你的代码有用到这个empty class时,编译器会默默的为你编写一些基本的函数.那么究竟编译器自己添加的函数都有哪些呢?构造函数,析构函数,一个copy构造函数和一个copy assignment操作符.举个例子来说明一下,如果你写下: class empty{}; 就好像你写下这样的代码: class Empty { public: Empty(){ ... } //default 构造函数 ~Empty(){ ....

第四篇:了解 C++ 默默编写并调用的函数

前言 对于一个类来说,最最基础的三类成员函数莫过于:构造函数,析构函数以及拷贝函数 (copy构造函数和=重载函数).即使你的类没有为这些函数做出定义,C++ 也会自动为你创建.本文将讲述的是 C++ “偷偷”为你创建的这三个函数究竟是怎么样的. 了解这些,能更清楚代码是如何运转的,从而写出自己需求的(这三类)函数,确保对象高效,节约. 默认的构造函数和析构函数 默认的构造函数/析构函数主要负责调用其基类的构造函数/析构函数. 默认的copy构造函数和=重载函数 默认的这两个函数仅仅是将对象的成

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

<前言>编译器是个十分敬业的工作者,不但为你编译代码,甚至为你生成代码,不可思议吧.本文主要介绍编译器究竟会为我们生成和调用哪些代码. <空类和非空类>如果问什么样的类是空类?也许你会说下面的类就是空类. class A{ }; 好吧,我也是这么认为的.没有构造函数怎么创建对象?事实上编译器会自动地把A的定义转为下面这样的代码. class A{ public: A() { } A(const A& rhs) { ... } ~A() { } A& operator

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

前言 对于一个类来说,最最基础的三类成员函数莫过于:构造函数,析构函数以及拷贝函数 (copy构造函数和=重载函数).即使你的类没有为这些函数做出定义,C++ 也会自动为你创建.本文将讲述的是 C++ “偷偷”为你创建的这三个函数究竟是怎么样的. 了解这些,能更清楚代码是如何运转的,从而写出自己需求的(这三类)函数,确保对象高效,节约. 默认的构造函数和析构函数 默认的构造函数/析构函数主要负责调用其基类的构造函数/析构函数. 默认的copy构造函数和=重载函数 默认的这两个函数仅仅是将对象的成

Effective C++ 条款5 了解C++默默编写并调用哪些函数

1. 成员函数只有被需要(被调用)才必须有定义,同理,只有当默认构造函数,拷贝构造函数,赋值操作符,析构函数被需要而类定义它们时,它们才会被编译器创建出来(除非函数在基类中被声明为虚函数,编译器产生的函数是非虚的,public的). 2. 并不是只要类没有定义默认构造函数,拷贝构造函数,赋值操作符时编译器就会自动合成它们,它们只有在"被需要"的时候才被产生. (具体见http://www.cnblogs.com/reasno/p/4742322.html) 3. 虽然编译器在类的创建者

C++编译器默默编写并调用哪些函数

什么时候empty class(空类)不再是个empty class呢?当C++处理过它之后,是的,如果你自己没有声明,编译器就会为它声明(编译器版本)一个copy构造函数.一个copy assignment操作符和一个析构函数.此外如果你没有声明任何构造函数,编译器也会为你声明一个default构造函数.所有这些都是public且inline. 编译器所生成的copy assignment操作符,其行为基本上与copy构造函数如出一辙,但一般而言只有当生出的代码合法且有适当机会证明它有意义,编