c++类中const属性的后期绑定

Late binding for const attributes in C++ classes?

本文关键字:绑定 属性 类中 const c++      更新时间:2023-10-16

我知道类属性没有延迟绑定。但是我需要一个好的模式来做到这一点:

#include <cstdlib>
#include <iostream>
using namespace std;
class B
{
public:
    const int i;
    B() : i(1) {}
};
class D : public B
{
public:
    const int i;
    D() : i(2) {}
};

int main()
{
    D d;
    B *ptr = &d;
    cout << ptr->i << endl;
    return 0;
}

输出是1,但我期望2。我想我应该换个图案。任何建议吗?

得到输出的i版本依赖于编译时类型定义。你定义了两个不同的变量,所以你会得到两个不同的结果。解决这个问题的方法是确保变量只有一个版本。可以在B中使用构造函数初始化const变量。

class B
{
public:
    const int i;
    B() : i(1) {}
protected:
    B(int j) : i(j) {}
};
class D : public B
{
public:
    D() : B(2) {}
};

您需要使用虚方法,就像c++中的所有后期绑定一样。

class B
{
public:
    virtual int get_i() const { return 1; }
};
class D : public B
{
public:
    virtual int get_i() const { return 2; }
};

您混淆了数据成员B::i(初始化为1)和D::i(初始化为2)。它们不相同,通过B *调用将获得B::i,而不是D::i

为了获得多态行为,你需要使用virtual函数。(Mark Ransom的回答中有另一种方法)

您只是在向派生类添加新成员,这也恰好隐藏了基类的成员。那不是你想要的。相反,使用虚函数:

class B
{
  int m_i;
public:
  virtual ~B() { }
  virtual int get() const { return m_i; }
};
class D : public B
{
  int m_j;
public:
  virtual int get() const { return m_j; }
};

用法:

D d;
B & b = d;
std::cout << b.get() << std::endl;  // correct dynamic dispatch

虚拟调度可以作用于函数成员,但不能作用于数据成员。

如果您迫切需要两个类中的同名变量,那么您可以使用访问器函数来完成这项工作:

#include <cstdlib>
#include <iostream>
using namespace std;
class B
{
    const int i;
public:
    B() : i(1) {}
    virtual int getI() { return i; }
};
class D : public B
{
    const int i;
public:
    D() : i(2) {}
    virtual int getI() { return i; }
};

int main()
{
    D d;
    B* ptr = &d;
    cout << ptr->getI() << endl;
}
// Output: 2

现场演示。