为什么C++没有虚拟变量?

Bru*_*uce 40 c++

这可能已被问过一百万次,或者可能是非常愚蠢但为什么没有实现呢?

class A
{
      public:
             A(){ a = 5;}
             int a;
};

class B:public A
{
      public:
             B(){ a = 0.5;}
              float a;
};

int main()
{
    A * a = new B();

    cout<<a->a;
    getch();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

此代码将访问A :: a.我如何访问B :: a?

Jos*_*ley 36

要访问B :: a:

cout << static_cast<B*>(a)->a;
Run Code Online (Sandbox Code Playgroud)

要显式访问A :: a和B :: a:

cout << static_cast<B*>(a)->A::a;
cout << static_cast<B*>(a)->B::a;
Run Code Online (Sandbox Code Playgroud)

(dynamic_cast有时比static_cast更好,但它不能在这里使用,因为A和B不是多态的.)

至于为什么C++没有虚拟变量:虚函数允许多态; 换句话说,他们通过调用代码使两个不同类型的类被视为相同,这两个类的内部行为的任何差异被封装在虚函数中.

虚拟成员变量实际上没有意义; 简单地访问变量就没有封装行为.

还要记住,C++是静态类型的.虚函数允许您在运行时更改行为; 您的示例代码不仅尝试更改行为,还尝试更改运行时的数据类型(A::aint,B::afloat),而C++不会以这种方式工作.如果需要在运行时容纳不同的数据类型,则需要在虚拟函数中封装这些差异,以隐藏数据类型的差异.例如(仅限演示代码;对于实际代码,您将重载运算符<<代替):

class A
{
  public:
         A(){ a = 5;}
         int a;
         virtual void output_to(ostream& o) const { o << a; }
};

class B:public A
{
  public:
         B(){ a = 0.5;}
         float a;
         void output_to(ostream& o) const { o << a; }
};
Run Code Online (Sandbox Code Playgroud)

还要记住,像这样公开成员变量可能会破坏封装,并且通常不赞成.

  • -1 这不能回答这个问题,因为 a) 打字问题也出现在虚函数中(想想 int foo() -&gt; float foo())但这很容易解决(第二个没有覆盖)和 b)虚拟变量可以通过函数调用隐式封装(虚拟函数也是如此)。唯一的答案似乎是第二个问题会很不方便,因为链接器需要知道虚拟变量和非虚拟变量之间的区别 (2认同)

Jam*_*ran 10

不公开数据,并通过虚函数访问它们.

考虑一下,你要求的是如何实施的.基本上,它会强制对任何数据成员的任何访问都通过虚函数.请记住,您通过指向A对象的指针访问数据,而A类不知道您在B类中所做的事情.

换句话说,我们可以在任何地方访问任何数据成员 - 或者您可以编写虚拟方法.猜猜哪些C++的设计师选择了......

  • 虚函数也是如此,必须通过查找表进行访问.但并不要求每个功能都是虚拟的.虚拟变量(相同类型 - 可能是指向多态对象的指针)将非常有意义 (7认同)