欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C++ --类的默认成员函数是否可以被定义为虚函数

程序员文章站 2024-03-17 08:00:51
...
1.静态成员函数不能定义为虚函数

1.因为静态成员函数没有this指针,并且静态成员函数可以通过类名来访问。
2.又因为虚函数是放在对象的虚表里面的,同一个类中的所有对象虽然共用同一张虚表,但是类名无法找到虚表。

2.内联函数不能定义为虚函数

因为内联函数没有地址,而虚表里面存放的就是虚函数的地址。

3.构造函数不能定义为虚函数

1.因为虚函数是存放在对象的虚表里面,如果将构造函数定义为虚函数,则构造函数也必须存放在虚表里面,但是此时对象都还没有创建也就没有所谓的虚表。
2.不将构造函数定义为虚函数,对象模型如下:
C++ --类的默认成员函数是否可以被定义为虚函数
3.如果将构造函数定义为虚函数:(直接会编译错误)
C++ --类的默认成员函数是否可以被定义为虚函数

4.尽量不要将operator=定义为虚函数

虽然operator=不会构成重写(因为父类与子类的operator=虽然返回值可能会构成协变,但是他们的参数不相同),但是如果将其定义为虚函数不仅会引起歧义,而且会编译器做复杂的事情。

5.不要在构造函数和析构函数里面调用虚函数

1.因为在构造函数里面对象是不完整的,所以虚表有可能还没创建好,就有可能发生未定义的行为。
2.在析构函数里面对象的某些成员会被清理,对象也可能不完整,所以也可能会发生某些未定义的行为。(未定义的行为指我们无法预知的行为)

6.最好将基类的析构函数声明为虚函数

1.对于某些场景,不将基类的析构函数声明为虚函数没有问题,例如如下场景:(下面的代码没有问题)

class A
{
public:
      A(int a = 0)
           :_a(a)
      {}

      ~A()
      {
           cout << "~A()" << endl;
      }
public:
      int _a;
};

class B : public A
{
public:
      ~B()
      {
           cout << "~A()" << endl;
      }
public:
      int _a;
};

int main()
{
      A a;
      B b;
      a = b;

      system("pause");
      return 0;
}

但是对于下面场景就会有问题

class A
{
public:
      A(int a = 0)
           :_a(a)
      {}

      ~A()
      {
           cout << "~A()" << endl;
      }
public:
      int _a;
};

class B : public A
{
public:
      ~B()
      {
           cout << "~B()" << endl;
      }
public:
      int _a;
};

int main()
{
      A* p = new B;
      delete p;
      system("pause");
      return 0;
}

C++ --类的默认成员函数是否可以被定义为虚函数
2.可以发现new上一个子类对象时,只调用了父类的析构函数,没有调用子类的析构函数,如果子类的析构函数里面含有类似于free之类的函数,则会导致内存泄露,所以必须要想办法调用子类的析构函数。
3.通过了解知道父类与子类的析构函数同名,都被编译器修饰为的destructor.

如果将父类的析构函数定义为虚函数,则父类与子类的析构函数构成多态(因为子类的析构函数数继承了父类析构函数的特性为virtual),指向父类调用父类的析构函数,指向子类调用子类的析构函数。

例如:(将父类的析构函数定义为虚函数)

class A
{
public:
      A(int a = 0)
           :_a(a)
      {}

      virtual ~A()
      {
           cout << "~A()" << endl;
      }
public:
      int _a;
};

class B : public A
{
public:
      ~B()
      {
           cout << "~B()" << endl;
      }
public:
      int _a;
};

int main()
{
      A* p = new B;
      delete p;
      system("pause");
      return 0;
}

C++ --类的默认成员函数是否可以被定义为虚函数

相关标签: 虚函数