代码之家  ›  专栏  ›  技术社区  ›  Js_zero

在c++中实例化对象有几种方法,它们之间有什么区别

  •  -3
  • Js_zero  · 技术社区  · 8 年前

    我是c++的新手,当我学习虚拟函数和纯虚拟函数时,我发现这与我以不同方式实例化对象时不同。这让我很困惑。如果你能帮忙,我将不胜感激。以下是代码和输出。

    #include <iostream>
    
    using namespace std;
    
    class A {
    public:
        int va;
        int vb;
    
        virtual void m1() {
            cout << "this is A's m1() method" << endl;
        }
    
        void m3() {
            cout << "this is A's m3() method" << endl;
        }
    };
    
    class B : public A {
    public:
        void m1() {
            cout << "this is B's m1() method" << endl;
        }
    
        void m2() {
            cout << "this is B's m2() method" << endl;
        }
    
        void m3() {
            cout << "this is B's m3() method" << endl;
        }
    };
    
    int main() {
        cout << "start" << endl;
        A a1 = B();
        a1.m1();
        a1.m3();
        cout << "===================" << endl;
        A *a2;
        a2 = new B();
        a2->m1();
        a2->m3();
        delete[]a2;
        /*
            output:
            this is A's m1() method
            this is A's m3() method
            ===================
            this is B's m1() method
            this is A's m3() method
        */
        return 0;
    }
    

    我想知道 A a1 = B(); A *a2; a2 = new B(); 。谢谢你的帮助。

    2 回复  |  直到 8 年前
        1
  •  0
  •   CygnusX1 Stack Overflow is garbage    8 年前

    你知道/学过Java吗?在C++中,情况有所不同。

    A a1 是类型的对象 A ,而不管您如何构建它。特别是:

    A a1 = B();
    

    是否执行以下操作:

    • 创建类型为的临时对象 B
    • 创建对象 a1 的类型 A. 使用内置的复制构造函数。会的 复制 临时文件的内容 a1级 。仅零件 A. 但将复制临时文件的。
    • 临时 B 对象已销毁。

    这就是为什么所有方法 a1级 都是真的 A. 方法。没有虚拟机制可以达到B的方法,因为 a1级 不是 B -键入对象。


    A* a2 另一方面,是指向任何类型对象的指针 A. 或衍生产品。它只是一个 指针 ,它本身并不表示对象。

    现在,当您分配 new B() 对于它,它将指向实际类型的对象 B 。通过此指针调用虚拟方法将达到 B 的方法如您所料。

    顺便说一句,通过指针引用的单个对象应通过删除 delete a2 。您使用 delete [] a2 如果您有一个数组。

        2
  •  0
  •   Eljay    8 年前

    我想知道 A a1 = B(); A *a2; a2 = new B();

    A a1=B(); 将B临时切片到A堆栈变量。B的任何其他成员变量或行为都将被丢弃。A堆栈变量 a1 将在作用域结束时销毁。

    A*a2;a2=新B(); 将有一个指向全局存储分配的B对象的指针。这个 a2 变量将指向该B对象,该对象继续是B对象。在B中重写的A的虚拟方法将使用B方法。A的非虚方法可以通过A指针访问,但B的其他方法(虚或非虚)将无法访问,除非使用强制转换。

    这个 delete[]a2; 是未定义的行为,并且在我的计算机上会使应用程序崩溃。因为B对象是使用在全局存储上分配的 new B() ,应使用删除 delete a2;