注意:不是C++ 11 Delegated Constructor Pure Virtual Method & Function Calls -- Dangers?的副本。这个问题涉及一个概念上类似的问题,并没有真正为这种情况提供解决方案。
考虑以下计划:
#include <iostream>
using std::cout;
using std::endl;
class Base {
virtual void init() = 0; // a hook function
public:
Base(int a, int b) { /* ... */ init(); }
Base(char a, int b) { /* ... */ init(); }
Base(char a, int b, double* c) { /* ... */ init(); }
/* etc. Dozens of constructors */
};
class Derived1 : public Base {
void init() { cout << "In Derived1::init()" << endl; }
public:
using Base::Base;
};
class Derived2 : public Base {
void init() { cout << "In Derived2::init()" << endl; }
public:
using Base::Base;
};
int main() {
Derived1 d1(1, 2);
Derived2 d2('a', 3);
return 0;
}
这段代码显然没有运行(尽管它在某些编译器上编译时会出现警告)。问题是,实现这种模式的最佳方法是什么?假设Base中有许多派生类和几十个构造函数,在派生类中重新实现Base构造函数(在派生构造函数的主体中调用base构造函数和init())并不是很理想。
答案 0 :(得分:2)
该代码需要在派生类构造函数中运行,在对象派生类型之前无法运行。
但是你可以使用完美转发
一次性地将它添加到所有构造函数中class Derived1 : public Base
{
public:
template<typename... T>
explicit Derived1(T&&... t) : Base(std::forward<T>(t)...) {
std::cout << "Derived1::init logic goes here" << endl;
}
};
答案 1 :(得分:1)
另一种方法是'命名'构造函数:
#include <iostream>
class Base
{
public:
template <typename Derived>
static Derived construct() {
Derived derived;
derived.hello();
return derived;
}
protected:
Base() {};
public:
virtual ~Base() {};
public:
virtual void hello() = 0;
};
class Derived : public Base
{
public:
virtual void hello() {
std::cout << "Hello\n";
}
};
int main ()
{
Derived d = Base::construct<Derived>();
}
答案 2 :(得分:0)
为那些在创建对象后调用init()
的类创建特殊工厂