5

我想初始化一个派生类的成员变量,然后将它传递给基类构造函数。我想出了下面的解决方案(也在这里:http ://cpp.sh/4uu4q )

1)以下代码是否具有已定义或未定义的行为(UB)?

2)我试图做的是否表明设计不好?

struct Data {
    int fValue;

    Data( int value = -1 ) : fValue( value )
    {}
};


struct Base {
    Base( const std::unique_ptr<Data> & derivedData ) {
        std::cout << "Constructing Base derivedData=" << derivedData->fValue << std::endl;
    }
};


struct Derived : public Base {
    std::unique_ptr<Data> fData = std::move( fData );

    Derived() : Base( ConstructData() )
    {}

    const std::unique_ptr<Data> & ConstructData() {
        fData.release();
        fData.reset( new Data(777) );
        std::cout << "in ConstructData: fData->fValue =" << fData->fValue << std::endl;
        return fData;
    }
};


int main() {
    Derived d;
    std::cout << "In main: d.fData->fValue =" << d.fData->fValue << std::endl;
    return 0;
}
4

1 回答 1

3

我想初始化一个派生类的成员变量,然后将它传递给基类构造函数。

在 C++ 中,构造顺序是基础部分在派生部分之前。这是因为派生零件(可能)根据基础零件构建更为常见。为了使这个定义明确,指定了 base-then-derived 顺序。因此,在基数中使用派生是未定义的。

如果您希望您的基地使用派生成员,有一种方法可以确保订单正常。也制作“成员”基类。请注意,这boost::base_from_member正是为了使这更方便而构建的。

说你有一些

class member_type{};

并且您想derived拥有一个member_type成员,并从base. 然后你可以使用:

class derived : 
    private boost::base_from_member<member_type>,
    public base {
    using my_member_type = private boost::base_from_member<member_type>;

public:
    derived();
};

请注意,现在derived子类my_member_typebase(按此顺序)。因此,后者可以在其构造中使用前者。

derived::derived() : 
    my_member_type{3},
    base{my_member_type::member} {
}
于 2016-09-21T12:33:11.767 回答