首页 > 试题广场 >

C++类体系中,不能被派生类继承的有?

[不定项选择题]
C++类体系中,不能被派生类继承的有?
  • 构造函数
  • 静态成员函数
  • 非静态成员函数
  • 赋值操作函数
A.构造方法用来初始化类的对象,与父类的其它成员不同,它不能被子类继承(子类可以继承父类所有的成员变量和成员方法,但不继承父类的构造方法)。因此,在创建子类对象时,为了初始化从父类继承来的数据成员,系统需要调用其父类的构造方法。
如果没有显式的构造函数,编译器会给一个默认的构造函数,并且该默认的构造函数仅仅在没有显式地声明构造函数情况下创建。
B.这其实不叫继承,这是可以全局调用的,静态函数不属于任何一个类的实例,在类被加载的时候,静态函数就会被创建,他的调用是通过类名调用的,所以你用子类类名调用父类静态函数和用父类类名调用这个静态函数完全一样没有任何区别

选A

发表于 2015-09-01 09:04:02 回复(1)
答案选A。
编译器总是根据类型来调用类成员函数。但是一个派生类的指针可以安全地转化为一个基类的指针。这样删除一个基类的指针的时候,C++不管这个指针指向一个基类对象还是一个派生类的对象,调用的都是基类的析构函数而不是派生类的。如果你依赖于派生类的析构函数的代码来释放资源,而没有重载析构函数,那么会有资源泄漏。所以建议的方式是将析构函数声明为虚函数。
也就是delete a的时候,也会执行派生类的析构函数。
一个函数一旦声明为虚函数,那么不管你是否加上virtual 修饰符,它在所有派生类中都成为虚函数。但是由于理解明确起见,建议的方式还是加上virtual 修饰符。

构造方法用来初始化类的对象,与父类的其它成员不同,它不能被子类继承(子类可以继承父类所有的成员变量和成员方法,但不继承父类的构造方法)。因此,在创建子类对象时,为了初始化从父类继承来的数据成员,系统需要调用其父类的构造方法。

如果没有显式的构造函数,编译器会给一个默认的构造函数,并且该默认的构造函数仅仅在没有显式地声明构造函数情况下创建。

构造原则如下:

    1. 如果子类没有定义构造方法,则调用父类的无参数的构造方法。

    2. 如果子类定义了构造方法,不论是无参数还是带参数,在创建子类的对象的时候,首先执行父类无参数的构造方法,然后执行自己的构造方法。

    3. 在创建子类对象时候,如果子类的构造函数没有显示调用父类的构造函数,则会调用父类的默认无参构造函数。

    4. 在创建子类对象时候,如果子类的构造函数没有显示调用父类的构造函数且父类自己提供了无参构造函数,则会调用父类自己的无参构造函数。

    5. 在创建子类对象时候,如果子类的构造函数没有显示调用父类的构造函数且父类只定义了自己的有参构造函数,则会出错(如果父类只有有参数的构造方法,则子类必须显示调用此带参构造方法)。

    6. 如果子类调用父类带参数的构造方法,需要用初始化父类成员对象的方式,比如:


#include <iostream.h>
class animal
{
public:
    animal(int height, int weight)
    {
        cout<<"animal construct"<<endl;
    }
};
class fish:public animal
{
public:
    int a;
    fish():animal(400,300), a(1)
    {
        cout<<"fish construct"<<endl;
    }
};
void main()
{
    fish fh;
}




编辑于 2015-01-22 16:57:02 回复(9)
赋值运算符重载函数 不是不能被派生类继承,而是被派生类的默认 赋值运算符重载函数 给覆盖了。

这就是 C++ 赋值运算符重载函数不能被派生类继承的真实原因!
发表于 2016-07-23 19:05:19 回复(5)
简而言之,缺省构造函数,拷贝构造函数,拷贝赋值函数,以及析构函数这四种成员函数被称作特殊的成员函数。这4种成员函数不能被继承
发表于 2016-08-26 22:39:49 回复(7)
答案:A
思路:构造函数是不能被继承的,但是可以被调用,如果父类重新定义了构造函数,也就是没有了默认的构造函数,子类创建自己的构造函数的时候必须显式的调用父类的构造函数。而其余的三个在我们平常的使用中都可以被继承使用。
编辑于 2016-06-02 21:24:19 回复(2)

为什么赋值运算符重载函数不能被继承呢?

     因为相较于基类,派生类往往要添加一些自己的数据成员和成员函数,如果允许派生类继承基类的赋值运算符重载函数,那么,在派生类不提供自己的赋值运算符重载函数时,就只能调用基类的,但基类版本只能处理基类的数据成员,在这种情况下,派生类自己的数据成员怎么办?

     所以,C++规定,赋值运算符重载函数不能被继承。

发表于 2017-02-19 10:53:07 回复(0)
发表于 2019-09-04 10:27:20 回复(2)
构造函数是不能被继承的, 背下来。
发表于 2016-01-09 11:32:23 回复(0)
个人认为,构造函数如果被继承了,你想想会发生些什么。是不是私有的成员变量也应该被公有化了,如果不公有化那你继承构造函数也就没有意义了
发表于 2016-01-10 12:40:34 回复(2)
本题答案有问题的,静态成员函数 不会被继承。即使子类调用,也只是个全局调用。故ABD,其实还有拷贝构造函数,析构函数
编辑于 2016-09-19 22:52:28 回复(1)
对于D,赋值操作函数不可以继承。其他运算符重载函数可以。
C++ 程序员的必读经典《 Effective C++ 》这么说:

条款 45:  弄清 C++ 在幕后为你所写、所调用的函数

一个空类什么时候不是空类?  ----  C++ 编译器通过它的时候。如果你没有声明下列函数,体贴的编译器会声明它自己的版本。这些函数是:一个拷贝构造函数,一个赋值运算符,一个析构函数,一对取址运算符。另外,如果你没有声明任何构造函数,它也将为你声明一个缺省构造函数。所有这些函数都是公有的。换句话说,如果你这么写:

class Empty{};

和你这么写是一样的:
class Empty {
public:
   Empty();                         // 缺省构造函数
   Empty(const Empty& rhs);         // 拷贝构造函数

   ~Empty();                        // 析构函数 ---- 是否
                                   // 为虚函数看下文说明
   Empty&
   perator=(const Empty& rhs);     // 赋值运算符

   Empty* operator&();              // 取址运算符
   const Empty* operator&() const;
};



C++ 标准规定: 如果派生类中声明的成员与基类的成员同名,那么,基类的成员会被覆盖,哪怕基类的成员与派生类的成员的数据类型和参数个数都完全不同。
所以, 赋值运算符重载函数 不是不能被派生类继承,而是被派生类的默认 赋值运算符重载函数 给覆盖了。

这就是 C++ 赋值运算符重载函数不能被派生类继承的真实原因
ref:
为什么C++赋值运算符重载函数不能被继承? 
 http://www.eetop.cn/blog/html/11/317611-14436.html


编辑于 2016-08-30 10:29:31 回复(2)
我也想说,c++11开始支持非默认构造函数继承了,在派生类中用using声明
发表于 2016-10-07 20:17:39 回复(2)
构造函数,析构函数 ,赋值运算 =,友元都不能继承C++primer 6 p530更详细
发表于 2016-08-20 19:37:15 回复(0)
赋值操作函数就是同类赋值,我傻了!!!
发表于 2022-07-10 10:35:37 回复(1)
构造函数 拷贝构造函数 析构函数 赋值操作符重载 以上不能继承
发表于 2018-07-25 00:52:13 回复(0)
静态成员函数怎么说?难道能被继承吗?这题还是有问题吧
发表于 2017-06-20 11:13:23 回复(0)
这道题本身就是有问题的好不好。首先C++11的构造函数可以支持继承了,只不过C++类体系中构造函数在默认情况下还是不支持继承的,出题的人就没点严谨?其次,赋值运算符重载函数可以继承?这么重要的 知识点都能弄错,我也真是服了出题者了。
编辑于 2016-05-03 20:19:41 回复(1)
构造方法用来初始化类的对象,与父类的其它成员不同,它不能被子类继承(子类可以继承父类所有的成员变量和成员方法,但不继承父类的构造方法)。因此,在创建子类对象时,为了初始化从父类继承来的数据成员,系统需要调用其父类的构造方法。
发表于 2016-09-08 22:07:41 回复(0)
赋值操作函数可以被继承:
#include <iostream>

class Base {
public:
    int baseValue;
    Base(int value) : baseValue(value) {}

    virtual void print() const {
        std::cout << "Base value: " << baseValue << std::endl;
    }
    virtual Base& operator=(const Base& other) {
        if (this == &other)
            return *this;
        baseValue = other.baseValue;
        std::cout << "operator= called "<< std::endl;
        return *this;
    }
};

class Derived : public Base {
public:
    int derivedValue;
    Derived(int base, int derived) : Base(base), derivedValue(derived) {}
    void print() const override {
        std::cout << "Derived value: " << derivedValue << std::endl;
    }
};
int main() {
    Derived derived1(10, 20);
    Derived derived2(30, 40);

    // Assigning a Derived object to another Derived object
    derived2 = derived1;

    // Print values
    //derived1.print();
    //derived2.print();

    return 0;
}


发表于 2023-09-24 17:37:37 回复(0)
选项B有问题,在《C++ primer 第5版 中文版》第532页有这个问题的描述,静态成员函数可以被派生类调用。
发表于 2023-04-21 08:29:43 回复(0)