【问题标题】:can a class have virtual data members?一个类可以有虚拟数据成员吗?
【发布时间】:2010-09-13 08:32:06
【问题描述】:
class Base{  
    public:  
        void counter();   
    ....   
}

class Dervied: public Base{  
    public:  
        ....  
}

void main()  
{  
     Base *ptr=new Derived;  
     ptr->counter();  
}

为了识别基类指针指向派生类并使用派生成员函数,我们使用“虚拟”。

同样,我们可以将派生数据成员设为“虚拟”吗? (数据成员是公开的)

【问题讨论】:

  • 显而易见的问题是为什么?它有什么需要?可能有其他方法可以解决这个问题。
  • 你(通常)不应该使用公共数据成员,而是使用访问器——因此你甚至不需要这个。
  • 请在您的伪代码中的某处添加单词virtual
  • @Georg:废话,公共数据成员有他们的位置。
  • @andre:只是一个想法:虚拟数据成员可以用于 mixins 或鸭子类型。当AB 两个类都定义virtual int count 时,继承A 和B 的派生类只能携带一个(因为它是虚拟的)count 成员。为此,基类要么需要具有兼容的布局,要么编译器可以自动创建同步两个基类的值的 getter/setter。

标签: c++ inheritance


【解决方案1】:

virtual 是一个函数说明符...

来自标准文档,

7.1.2 函数说明符 函数说明符只能在函数声明中使用。 函数说明符: 排队 虚拟的 明确的

所以没有什么叫做虚拟数据成员

希望对你有帮助...

【讨论】:

【解决方案2】:

不,但是你可以创建一个虚函数来返回一个指向你所谓的虚数据成员的指针

【讨论】:

  • 你可能不能这样做,因为它可能会导致访问冲突。
  • 这需要格外小心
【解决方案3】:

不,在 C++ 中没有虚拟数据成员。

【解决方案4】:

我不这么认为,但您也许可以使用虚拟 getter 和 setter 来模拟它?

【讨论】:

    【解决方案5】:

    为了识别基类指针指向派生类并使用派生成员函数,我们使用“虚拟”。

    这是不正确的。我们制作虚函数以允许派生类提供与基类提供的不同的实现。不用于标识基类指针指向派生类。

    同样,我们可以将派生数据成员设为“虚拟”吗? (数据成员是公开的)

    只有非静态成员函数可以是虚函数。数据成员不能。

    Here's 包含更多信息的链接

    【讨论】:

    • “我们制作虚函数以允许派生类提供与基类提供的不同的实现。”不完全是,当您创建派生类并编写与超类中的函数同名的函数时,您已经明白了。 virtual 所做的是允许您将对象强制转换为其超类之一,但仍将派生类的实现用于虚函数。 (换句话说,C++ 对普通函数使用静态调度,对虚拟函数使用动态调度。)
    【解决方案6】:

    不,因为这会以无数意想不到的方式破坏封装。无论您想实现什么,都可以使用受保护的属性和/或虚函数来完成。

    另外,虚函数是dispatch的一种方法(即选择调用哪个函数),而不是选择成员属性对应的内存位置。

    【讨论】:

    • 您能否提供一个或两个例子来说明这是一个问题(这已经不是钻石继承的问题了)?我一直想知道这个决定的原因。
    【解决方案7】:

    也许你可以用等效的方式看到问题:

    class VirtualDataMember{  
        public:  
        ...
    }
    
    class DerviedDataMember: public VirtualDataMember{  
        public:  
        ... 
    }
    
    class Base{  
        public:  
            VirtualDataMember* dataMember;
            void counter();     
            ...  
    }
    

    【讨论】:

      【解决方案8】:

      一个类不能有一个虚拟成员,例如这个answer。 但是,您可以使用指针、继承等类似的东西 和运行时多态性。

      在下面的 sn-p 中,我定义了几何 shape 的原型, 有一个area 方法。 picture 类有一个成员 shape* s;s指向的shape的方法被picture::show()使用。 在此设置中,不希望在之前有 picture 的实例 给出了 shape 的实际实现,因此我们强制 picture 为 通过添加一个虚拟虚函数picture::make_real()进行抽象。

      // prototypes
      class shape
      {
          public:
          virtual double area() = 0; // to be defined later
      };
      class picture
      {
          protected:
          shape* s;
          
          virtual void make_real() = 0; // force picture to be abstract
          
          public:
          picture(shape* ptr):
              s{ptr}
          {}
          
          void show()
          {
              std::cout << s->area() << '\n';
          }
      };
      
      

      接下来,我们实际上实现了一个名为squareshape 和一个picture 类型 square_picture(字面意思)有一个squareshape

      // actual implementation
      
      class square : public shape
      {
          double len;
          
          public:
          square(double l):
              len{l}
          {}
           
           double area() override
          {
              return len*len;
          }
      };
      
      
      
      class square_picture : public picture
      {
          void make_real() override {} // square_picture is not abstract
          
          public:
          square_picture(double l):
              picture{new square{l}}
          {}
          
          ~square_picture()
          {
              delete s;
          }
      };
      

      square_picture可以用下面的sn-p测试

      int main()
      {
          square_picture A{2.0};
          A.show();
          
          //picture B{nullptr}; // error: picture is abstract
          return 0;
      }
      

      哪个输出:

      4
      

      【讨论】:

        【解决方案9】:

        我有一个使用对象数组的基类。我从那个类派生了一个使用不同类型对象数组的新类。两个变量的名称完全相同。两个类都添加了虚拟成员函数来处理数组。这些成员函数可以轻松找到正确的变量。成员函数和它们使用的变量在一个公共范围内。

        两个类中的虚拟成员函数几乎相同。只有数组的类型发生了变化。

        C++ 模板也可以达到同样的效果。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-01-22
          • 1970-01-01
          • 2010-11-14
          • 1970-01-01
          • 2011-04-08
          相关资源
          最近更新 更多