不能说是不能继承。通常情况下,子类的构造函数和析构函数一般会包含父类的流程。
默认情况下,构造对象时,先调用父类的构造函数,然后调用子类的构造函数。
销毁时是相反的,先调用子类的析构函数,再调用父类的析构函数。
赋值运算符在程序员不重写的情况下,编译器会默认生成一个,但是它做的事情是位拷贝,和隐式拷贝构造函数一样,就是说,当A = B时,它是把B的整个这块内存中的内容直接按位拷贝给A的内存,这样的后果就是当该类的成员有指针时,就很容易发生野指针造成程序崩溃。所以,当成员存在指针时,程序员应当重写赋值运算符。
书上不能继承的含义可能就是它是一种集合包含的关系而不是父子继承的关系,而赋值运算符,上述两种关系都不算。
希望对撸主有帮助。
类似的解释应该是有的,不过可能比较零散。
不能继承构造函数:意味着子类不能覆盖这类函数,(就是说构造函数不能为虚)。另,不能把父类的构造函数当子类的成员函数来调用(这一点很关键,因为继承本质上意味着父类的成员就是子类的成员)。
子类的构造函数执行其他任何操作前,必须先调用父类的构造函数(除非父类没有构造函数),初始化父类地址空间成员。子类的构造函数可以指定由调用父类哪个构造函数(如果父类有重载多个构造函数),如果不指定,默认调用无参构造函数。
不能继承析构函数:子类可以覆盖父类的析构函数,不能把父类的析构函数当子类的成员函数来调用。
不能继承赋值运算符重载函数:
http://www.pconline.com.cn/pcedu/empolder/gj/c/0504/588320.html
这个网址解释了赋值运算符重载函数。不能继承,意味着当子类对象的赋值过程(当作左值对象已存在时)是通过直接按位拷贝(浅拷贝),而非调用父类的赋值运算符重载函数。
上面几个“不能继承”虽然其限制条件不太一样,但是都有一个共同点:父类的成员不是子类的成员。
什么是“成员”?
对于非静态成员,
可以这样访问的:
对象名.成员名
或:
指针名->成员名
在子类内部可以这么访问:
this->成员名。
至于静态成员则是:
类名::成员名
请问能通过此方法访问父类的那三种函数吗?显然不行。
class Base
{
Base( int ) { ... }
Base( const Base& rhs ) { ... } // 复制构造函数, 可以继承
Base& operator=( const Base& rhs ) { return *this ; } // 复制赋值操作符, 可以继承
Base& operator=( int x ) { ... return *this ; } // 赋值运算符重载函数, 不能继承
} ;
class Derived : public Base
{ } ;
int main()
{
Base b( 10 ) // okay, general construction
Derived d( 10 ) ; // error, 你不能继承父类的构造函数
Base b2( b ) ; // okay, copy construction
Derived d2( d ) ; // okay, 调用Base::Base(const Base& ), 结果是部分复制.
Base b3 ; b3 = b ;// okay, copy assignment
Derived d3 ; d3 = d ; .// okay, 调用Base::operator=( const Base& ), 结果是不完全赋值
b = 4 // okay , call Base::operator=( int ) ;
d = 4 // error
}
作者的意思是,你得自己定义这些函数
不能继续原因很简单. 这些复制控制函数会初始化,或销毁自己的成员, 在基类中, 根本就不可能
知道远程子类的成员, 更不用谈初始化或者销毁它们.
所以大部分情况都是子类在自己的构造函数中调用父类构造函数,初始化父类成员, 然后再初始化自己的成员
网上没有多谈这些的原因是.
熟悉C++面向对象的人自然而然理解为什么不能继承.
不熟悉C++面向对象的人, 根本就想不到这类问题.
所以你应该是少部分懂?不懂?的人.
class Base
{
Base( int ) { ... }
Base( const Base& rhs ) { ... } // 复制构造函数, 可以继承
Base& operator=( const Base& rhs ) { return *this ; } // 复制赋值操作符, 可以继承
Base& operator=( int x ) { ... return *this ; } // 赋值运算符重载函数, 不能继承
} ;
class Derived : public Base
{ } ;
int main()
{
Base b( 10 ) // okay, general construction
Derived d( 10 ) ; // error, 你不能继承父类的构造函数
Base b2( b ) ; // okay, copy construction
Derived d2( d ) ; // okay, 调用Base::Base(const Base& ), 结果是部分复制.
Base b3 ; b3 = b ;// okay, copy assignment
Derived d3 ; d3 = d ; .// okay, 调用Base::operator=( const Base& ), 结果是不完全赋值
b = 4 // okay , call Base::operator=( int ) ;
d = 4 // error
}
不能继承构造函数:意味着子类不能覆盖这类函数,(就是说构造函数不能为虚)。另,不能把父类的构造函数当子类的成员函数来调用(这一点很关键,因为继承本质上意味着父类的成员就是子类的成员)。
子类的构造函数执行其他任何操作前,必须先调用父类的构造函数(除非父类没有构造函数),初始化父类地址空间成员。子类的构造函数可以指定由调用父类哪个构造函数(如果父类有重载多个构造函数),如果不指定,默认调用无参构造函数。
不能继承析构函数:子类可以覆盖父类的析构函数,不能把父类的析构函数当子类的成员函数来调用。
final
加在成员函数声明后面。