Effective C++(1)------------------------------构造/析构/赋值

今天开始看effective C++了,感觉写的不错,特此用自己的语言记录一下加深印象~

1.得了解C++编译器会默认编写并调用哪些函数

//当声明一个空类时,编译器会为这个类默默编写4个函数并调用他们以便实现类的功能
class A
{
};

//在编译器的支持下,上面这个空类等价于下面这个类
class A
{
  public:
      A(){};   //default构造函数
      A(const A&){}; //拷贝构造函数
      A& operator=(const A&){}; //拷贝赋值操作符
      ~A(){};  //析构函数
};

2.C++允许让一个指向父类的指针指向这个父类的派生类,但并不允许指向一个派生类的指针指向其父类,这么做会导致未定义的结果。

class A
{
  public:
      int a;
};

class B : public A
{
  public:
      int b;
};

A* p=new A;
   p=new B;
//从上面两个类来看,分配给类A的实例的内存占4个字节(32bit),而分配给类B的实例的内存占8个字节
//那么让p指向一个类B的实例后,指针p只能访问继承来的前四个字节

B* p2=new B;
   p2=new A;
//上面这么做的结果就是未定义

3.C++通过引入虚函数实现多态性,这样就可以用指向父类的指针去执行各个派生类各自的行为了。同时也要注意为多态基类声明虚析构函数(多态基类就是类中至少有一个虚函数,因为有一个虚函数就表示期待被继承),同时也并不是所有类都得用虚析构函数,只要当这个类要被继承时(其中有虚函数)使用虚析构函数,目的就是使得派生类的实现得以客制化(当一个派生类对象被一个基类的指针delete时,不会有内存泄漏)。

#include <iostream>
using namespace std;
class A
{
   public:
            A(){cout<<"A constructor"<<endl;};
            ~A(){cout<<"A destructor"<<endl;};
            virtual void fun(){cout<<"A"<<endl;};
            //virtual ~A(){cout<<"A destructor"<<endl;};
};

class B : public A
{
   public:
       B(){cout<<"B constructor"<<endl;};
       ~B(){cout<<"B constructor"<<endl;};
       void fun(){cout<<"B"<<endl;};
};

int main()
{
   A* p=new B;
      p->fun();
   delete p;            //会出现未定义行为,必须给A类加上一个虚析构函数
   return 0;
}

4.常说的浅拷贝是指编译器默认生成的拷贝函数(实质上是将内存复制过去),如果要是这个类里有指针就不好办了。这个时候我们就会有深拷贝这个说法了,深拷贝就是我们重新写一个拷贝构造函数,但是要注意的是如果我们一旦重写自己的拷贝构造函数,在你的代码几乎出错的时候编译器也不会告诉你。

时间: 2024-11-08 18:46:02

Effective C++(1)------------------------------构造/析构/赋值的相关文章

《Effective C++》构造/析构/赋值 函数:条款5-条款9

每一个类中都有构造函数.析构函数.赋值操作符.这几个函数是一个类最根本的函数,它控制着创建对象并初始化.对象消亡时的清理以及摆脱旧值赋新值.这样函数如果有问题,那么影响极为严重. 条款5:了解C++默认编写并调用哪些函数 加入编写一个空类,那么经过编译之后,C++默认编写了哪些函数. class Empty{ }; 经过编译器处理后会有默认构造函数.复制构造函数.赋值操作符和析构函数.这些函数都是public且inline. class Empty{ public: Empty(){} Empt

【Effective C++】构造/析构/赋值运算

条款05:了解C++默默编写并调用哪些函数 默认构造函数.拷贝构造函数.拷贝赋值函数.析构函数构成了一个类的脊梁,只有良好的处理这些函数的定义才能保证类的设计良好性. 当我们没有人为的定义上面的几个函数时,编译器会给我们构造默认的. 当成员变量里有const对象或引用类型时,编译器会不能合成默认的拷贝赋值函数:当一个基类把它的拷贝赋值函数定义为private时,它的派生类也不无生成默认的拷贝赋值函数,因为它无法完成基类成份的赋值. 条款06:若不想使用编译器自动生成的函数,就该明确拒绝 将拷贝构

《Effective C++》构造/析构/赋值 函数:条款10-条款12

条款10:令operator=返回一个reference to *this 赋值操作符运算是由右向左运算的.例如一个连锁赋值 <span style="font-size:14px;">int x, y, z; x=y=z=15;</span> 编译器解释时时这样的: x=(y=(z=15)); 先给z赋值,用赋值后的z再给y赋值,用赋值后的y再给x赋值. 为了实现连锁赋值,操作符必须返回一个reference指向操作符左侧的实参. 其实,如果operator=

Effective C++ 02构造/析构/赋值运算(待续)

条款05:了解C++默默编写并调用哪些函数 如果你自己没声明,编译器就会为类声明(编译器版本的)一个拷贝构造函数,一个拷贝赋值操作符和一个析构函数. 此外如果你没有声明任何构造函数,编译器也会成为你声明一个默认构造函数.所有这些函数都是public且inline. 惟有当这些函数被需要(被调用),它们才会被编译器创建出来.即有需求,编译器才会创建它们. 请记住: 编译器可以暗自为类创建默认构造函数.拷贝构造函数.拷贝赋值操作符,以及析构函数. 条款06:若不想使用编译器自动生成的函数,就该明确拒

Effective C++笔记:构造/析构/赋值运算

条款05:了解C++默默编写并调用哪些函数 默认构造函数.拷贝构造函数.拷贝赋值函数.析构函数构成了一个类的脊梁,只有良好的处理这些函数的定义才能保证类的设计良好性. 当我们没有人为的定义上面的几个函数时,编译器会给我们构造默认的. 当成员变量里有const对象或引用类型时,编译器会不能合成默认的拷贝赋值函数:当一个基类把它的拷贝赋值函数定义为private时,它的派生类也不无生成默认的拷贝赋值函数,因为它无法完成基类成份的赋值. 条款06:若不想使用编译器自动生成的函数,就该明确拒绝 将拷贝构

《Effective C++》第2章 构造/析构/赋值运算(2)-读书笔记

章节回顾: <Effective C++>第1章 让自己习惯C++-读书笔记 <Effective C++>第2章 构造/析构/赋值运算(1)-读书笔记 <Effective C++>第2章 构造/析构/赋值运算(2)-读书笔记 <Effective C++>第8章 定制new和delete-读书笔记 条款09:绝不在构造和析构过程中调用virtual函数 你不该在构造和析构函数期间调用virtual函数,因为这样的调用不会带来你预期的结果. (1)在der

《Effective C++》第2章 构造/析构/赋值运算(1)-读书笔记

章节回顾: <Effective C++>第1章 让自己习惯C++-读书笔记 <Effective C++>第2章 构造/析构/赋值运算(1)-读书笔记 <Effective C++>第8章 定制new和delete-读书笔记 条款05:了解C++默默编写并调用哪些函数 当C++处理过一个空类后,编译器就会为其声明(编译器版本的):一个拷贝构造函数.一个拷贝赋值运算符和一个析构函数.如果你没有声明任何构造函数,编译器还会声明一个默认构造函数.所有这些函数都被声明为pub

[Effective C++]构造/析构/赋值运算

条款05:了解C++默默编写了并调用了那些函数 请记住: 编译器可以暗自为class 创建default构造函数,copy构造函数,copy assignment 操作符,以及析构函数 class Empty { public: Empty(){...} //default constructor Empty(const Empty& rhs){...} //copy constructor ~Empty(){...} //destructor Empty& operator=(const

c++笔记:const、初始化、copy构造/析构/赋值函数

构造函数 Default构造函数:可被调用而不带任何实参的构造函数,没有参数或每个参数都有缺省值.如: class A { public: A(); }; 将构造函数声明为explicit,可阻止它们被用来执行隐式类型转换,但仍可用来进行显示类型转换.如: class B { public: explicit B(int x = 0, bool b = ture); }; copy构造函数:用于以同型对象初始化自我对象,以passed by value的方式传递对象:· copy assignm