C++ 的行为对象参考

发布于 2024-10-08 18:15:30 字数 950 浏览 13 评论 0原文

考虑以下代码段:

class Window // Base class for C++ virtual function example
     {
       public:
          virtual void Create() // virtual function for C++ virtual function example
          {
               cout <<"Base class Window"<<endl;
          }
     };

     class CommandButton : public Window
     {
       public:
          void Create()
          {
              cout<<"Derived class Command Button - Overridden C++ virtual function"<<endl;
          }
     };

     int main()
     {
        Window *button = new   CommandButton;
        Window& aRef = *button;
        aRef.Create(); // Output: Derived class Command Button - Overridden C++ virtual function
        Window bRef=*button;
        bRef.Create(); // Output: Base class Window

        return 0;
     }

aRefbRef都被分配了*button,但是为什么两个输出不同。 分配给引用类型和非引用类型有什么区别?

Consider the following code segment:

class Window // Base class for C++ virtual function example
     {
       public:
          virtual void Create() // virtual function for C++ virtual function example
          {
               cout <<"Base class Window"<<endl;
          }
     };

     class CommandButton : public Window
     {
       public:
          void Create()
          {
              cout<<"Derived class Command Button - Overridden C++ virtual function"<<endl;
          }
     };

     int main()
     {
        Window *button = new   CommandButton;
        Window& aRef = *button;
        aRef.Create(); // Output: Derived class Command Button - Overridden C++ virtual function
        Window bRef=*button;
        bRef.Create(); // Output: Base class Window

        return 0;
     }

Both aRef and bRef get assigned *button, but why are the two output different.
What is the difference between assigning to Reference type and non Reference type?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

素衣风尘叹 2024-10-15 18:15:30

您遇到了切片问题。

Window bRef   =*button;

这里bRef不是引用而是对象。当您将派生类型分配给 bRef 时,您将切掉派生部分,只留下一个由 CommandButton 构造的 Window 对象。

所发生的情况是,bRef 是在上面的语句中使用编译器为 Window 类生成的复制构造函数创建的。这个构造函数所做的就是将成员元素从 RHS 复制到新构造的对象。由于该类不包含任何成员,所以什么也没有发生。

旁注:具有虚拟成员的类也应该有一个虚拟析构函数。

You have encountered the slicing problem.

Window bRef   =*button;

Here bRef is not a reference but an object. When you assign a derived type onto bRef you are slicing the derived part off leaving you with just a Window object constructed form a CommandButton.

What is happening is that bRef is created in the above statement using the compiler generated copy constructor for the class Window. All this constructor does is copy member elements from the RHS to the newly constructed object. Since the class contains no members nothing is happening.

On a side note: A class with virtual members should also have a virtual destructor.

停滞 2024-10-15 18:15:30
  • aRef 具有 Window static 类型,但 CommandButton dynamic 类型
  • bRef 只是一个 Window 类型的对象(CommandButton 'part' 在副本中丢失了

)通常称为对象切片,通常通过使基类抽象(通过提供纯虚函数)或不可复制(例如使用 boost::noncopyable),因为任何一种解决方案都会使代码无法在线编译 Window& 。 aRef = *按钮;。


现在,为什么 bRef.Create() 调用 Window::Create ?好吧,bRef 中除了一个 Window 之外什么也没有,所以确实没有太多的选择。这本质上就像声明一个 Window 并在其上调用 Create :事实上 bRef 是从 CommandButton 复制的实例不相关,因为 CommandButton 部分在副本中丢失。

我将尝试通过引用标准 (10.3/6) 来使这一点更清楚:

[注:调用的解释
虚函数的值取决于
其所属对象的类型
称为(动态类型),而
a 的调用的解释
非虚成员函数取决于
仅取决于指针的类型或
表示该对象的引用(
静态类型
)(5.2.2)。 ]

只有通过指针或间接引用,对象的静态类型才能与其动态类型不同。

  • aRef has Window static type but CommandButton dynamic type
  • bRef is simply an object of type Window (the CommandButton 'part' was lost in the copy)

This is commonly known as object slicing and it usually prevented by making base classes either abstract (by providing a pure virtual function) or non copyable (for example using boost::noncopyable), because either solution would make the code fail to compile on line Window& aRef = *button;.


Now, why does bRef.Create() call Window::Create ? Well, there is nothing more than a Window in bRef so there really isn't much of an alternative. This is essentially like declaring a Window and calling Create on it : the fact that bRef was copied from a CommandButton instance is irrelevant because the CommandButton portion was lost in the copy.

I'll try to make this clearer by quoting the standard (10.3/6) :

[Note: the interpretation of the call
of a virtual function depends on the
type of the object for which it is
called (the dynamic type), whereas the
interpretation of a call of a
nonvirtual member function depends
only on the type of the pointer or
reference denoting that object (the
static type
) (5.2.2). ]

Only through a pointer or reference indirection can the static type of an object differ from its dynamic type.

手心的温暖 2024-10-15 18:15:30
Window bRef=*button;
bRef.Create(); // Output: Base class Window

bRef 的静态和动态类型仅限于Window。虚拟机制仅适用于引用和指针。 bRef 是一个对象,而不是引用或指针。

Window bRef=*button;
bRef.Create(); // Output: Base class Window

The static as well as dynamic type of bRef is Window only. Virtual mechanism works only with references and pointers. bRef is an object not a reference or a pointer.

单挑你×的.吻 2024-10-15 18:15:30
 Window bRef=*button;
 bRef.Create(); // Output: Base class Window

这里的 bRef 不是对 button 的引用(您只是这样命名的)。 bRef 仅获取基本子对象,即Window

 Window bRef=*button;
 bRef.Create(); // Output: Base class Window

Here bRef is not the reference to button (you just named it so). bRef gets only the base subobject which is Window.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文