有没有办法从基础实例创建派生实例?

时间:2014-09-02 21:15:52

标签: c++ inheritance constructor

我想将一些基本信息注入它可以构建的派生类中。派生类不应该关心初始化这些信息,它应该就在那里。

通过继承可以轻松实现这一目标。但问题是基类本身并不知道这些值。相反,它们需要作为参数传递。但是,由于派生类不需要处理这个问题,因此通过派生构造函数对参数进行隧道处理是不可取的。

我能想到的唯一解决方案是静态地提供信息,以便基类可以在没有帮助的情况下获取它们。但我想避免这种情况。

有没有办法首先创建和初始化基类,然后将实例扩展到派生类型?如果没有,我如何使用C ++的可用功能实现这种创建和依赖的顺序?

#include <string>
#include <iostream>
using namespace std;

class Base {
public:
    Base(string name, int age) : name(name), age(age) {}
protected:
    const string name;
    int age = 0;
};

class Derived : public Base {
    Derived() { // No parameters here, no call to base constructor
        cout << "My name is " << name << " and I'm " << age << "." << endl;
    }
}

Base base("Peter", 42);
Derived derived(base); // "My name is Peter and I'm 42."

3 个答案:

答案 0 :(得分:6)

&#34;信息应该在那里&#34;听起来像是它允许两种可能的解释:

  • 信息实际上是全局不变的,可以硬编码:

    Derived() : Base("Peter", 42) {}
    
  • 你真正的意思是&#34;基地应该就在那里&#34;:

    Derived(const Base & b) : Base(b) {}
    

答案 1 :(得分:5)

由于某种原因,无法将已分配的类型扩展为派生类型:如果派生类型添加了字段,您将如何预先确定正确的大小?

一种可能的方法是只接受Base实例或operator=实例的构造函数。

但是在此示例中,您可能需要考虑使用合成而不是继承。如果Base仅用作Derived的模板,则它不是继承关系的好例子。

答案 2 :(得分:3)

一种选择是使用合成,这意味着Base将是Derived的实例变量:

#include <string>
#include <iostream>
using namespace std;

class Base {
public:
    Base(string name, int age) : name(name), age(age) {}
    const string name() { return name; }
    int age() { return age; }
protected:
    const string name;
    int age = 0;
};

class Derived {
    Derived(Base b): base(b) { // No parameters here
        cout << "My name is " << base.name() << " and I'm "
             << base.age() << "." << endl;
    }

private:
    Base base;    
}

Base base("Peter", 42);
Derived derived(base); // "My name is Peter and I'm 42."

注意Derived不再扩展Base(可能需要更改名称),并且Base中对实例变量的每次调用现在都是方法调用。< / p>