覆盖基类成员变量的初始值

时间:2016-01-04 13:33:48

标签: c++ inheritance

我现在对继承感到非常困惑。我打算简单地覆盖变量的初始值。在下面的代码中,我只是继承了基类并尝试获取它的名称,该名称保存为带有该类的字符串。我期望派生类可以覆盖此值,但它不会这样做。

我的预期出局是

val phDf = sqlContext.phoenixTableAsDataFrame("TABLE1", Array("ID", "NAME"), conf = hbaseConf)

但是我得到了

Derived
Derived

实施以下内容的正确方法是什么?

Base
Base

4 个答案:

答案 0 :(得分:3)

  

实施以下内容的正确方法是什么?

听起来没有意义,这实际上取决于你想要达到的目标。

我要猜测我们只是在询问一个对象是什么类型,无论我们调用哪个接口:

struct Base {
  virtual ~Base() = default;

  virtual const std::string id() const {
    return "Base";
  }
};

struct Derived : Base {
  virtual const std::string id() const override {
    return "Derived";
  }
};

这是另一种方式:

struct Base {
  virtual Base(std::string ident = "Base") 
  : _id(std::move(ident))
  {}

  virtual ~Base() = default;

  std::string& id() const {
    return _id;
  }

private:
  std::string _id;

};

struct Derived : Base {
  Derived() : Base("Derived") {}
};

另外,使用值是接口,但请注意,这将禁用赋值运算符

struct Base {
  virtual Base(std::string ident = "Base") 
  : id(std::move(ident))
  {}

  virtual ~Base() = default;

  const std::string id;

};

struct Derived : Base {
  Derived() : Base("Derived") {}
};

此列表并非详尽无遗。

答案 1 :(得分:2)

存在虚函数,而非虚拟成员变量。

您在Derived课程中所做的是定义一个隐藏它的父级的新成员变量id_。但是,id()函数指的是该上下文中id_定义的

如果要覆盖行为,则应覆盖id()函数:

class Derived: public Base {
    std::string id() const override { return "Derived"; }
};

答案 2 :(得分:1)

为什么不简单地给Base一个构造函数设置id并让Derived调用此构造函数及其被覆盖的'值?繁荣:'虚拟数据'根据派生类型。

话虽如此,虚拟方法可能更类似于封装,并为以后更精细的行为提供机会。

编辑:我将此作为评论发布,然后将其转换,此时理查德刚刚击败我发布答案。没有复制!

答案 3 :(得分:0)

由于函数id()是虚拟的,因此在两种情况下,对象指针都只是派生类型。

Base* b = new Derived(); // object type is Derived
b->id();

这里b是Derived类型的指针 但是" Derived" class没有id()的实现,因为在虚拟查找表中没有id()的条目用于派生类对象,因此它将调用基类函数id()

同样其他情况

Derived* d = new Derived(); //object type is Derived
d->id();

因为在派生类中没有定义id()方法,所以它只会调用基类id()。

另一个疑问是你如何初始化变量" id _"在班里?