c ++:继承构造函数,但通过在构造函数中调用的编辑方法进行更改

时间:2018-03-06 19:59:23

标签: c++

假设我有一个基类,

#include <stdio.h>
#include <stdint.h>

int popcount( uint8_t byte )
{
    int count = 0 ;
    for( uint8_t b = 0x01; b != 0; b <<= 1 )
    {
        count = count + (((byte & b) != 0) ? 1 : 0) ;
    }

    return count ;
}

int main()
{
    int valuecount[8] = {0} ;
    for( int i = 0; i < 256; i++ )
    {
        valuecount[popcount(i)]++ ;    
    }

    printf( "popcount\tvalues\n") ;
    for( int p = 0; p < 9; p++ )
    {
        printf( "   %d\t\t  %d\n", p, valuecount[p] ) ;
    }

    return 0;
}

我想创建一个后代,但我只需要在构造函数中调用的一个方法中更改几行:

popcount        values 
   0              1
   1              8
   2              28
   3              56
   4              70
   5              56
   6              28
   7              8
   8              1

现在,当我致电n时,我应该按预期获得n / 2结构,对吗?

我如何在C ++中执行此操作?

3 个答案:

答案 0 :(得分:2)

  

现在,当我调用Y(classC输入)时,我应该按照预期得到我的Y结构,对吗?

错误。继承构造函数并不意味着使用由您重载的函数调用替换的函数调用来重新创建它的主体。这意味着构造Y就足以通过该c'tor显式构造X子对象。因此,您可以将适当的c'tor拉入Y以供使用。

这意味着,同样的身体。其他所有Y特定的内容都将默认初始化。

  

我如何在C ++中执行此操作?

简单地说,你不能轻易做到。除非你搞乱黑暗模板魔法,否则X::X将始终调用X::do_this。您也可以将do_this移动到其他类,并使用 一个多态,但正如您所提到的,这不是一个选项。

如果您想添加电话Y::do_this,请为Y写一个c'tor。但它不会取代对X::do_this的调用,之后会发生。这就是C ++对象模型。

答案 1 :(得分:1)

只要类Y继承自类X而类X没有默认构造函数,就必须在重载类(Y)中显式调用其重载版本:< / p>

class X{
    public:
        X(int _x) : x(_x){};
    private:
        int x;
};

class Y : public X{
    public:
        Y() : X(0){} // important
};


int main() {

    Y y; // if you remove the default constructor of Y you'll get an error here

    return 0;
}

答案 2 :(得分:1)

这很难,因为唯一好的方法是使用virtual函数。但是,这在此不可行,因为构造函数中的virtual方法是静态解析的。这意味着,如果您有类A和类B : A并且它们都已实现虚函数foo,那么当您在基类构造函数中调用foo时,它将始终使用基类实现。

一种方法是像这样使用它:

class A {
public:
    A(whatever) { }
    virtual void initialize() {
        // base class impl
    }
};
class B : public A{
public:
    // if no base default ctor, use
    // B(whatever)
    //     : A(whatever)
    B(whatever) {
    }
    virtual void initialize() override {
        // derived class impl
    }
};

template <typename T> // constraint it if you want.
T createObject() {
    T object;
    object.initialize(); // resolved dynamically
}