C++对象实例化方式有哪些?不同方式之间的差异是什么?
Hey there, no worries—virtual functions can feel tricky at first, but let’s break this down step by step. I’ll cover the key points that usually trip up newbies when it comes to instantiation and virtual behavior, using your code snippet as a starting point.
First, let’s recap the basics to set the stage:
- Virtual functions: Let derived classes override a base class method, and the correct version is called based on the actual type of the object (not the pointer/reference type).
- Pure virtual functions: A virtual function declared with
= 0(likevirtual void m2() = 0;). These turn the class into an abstract class—you can’t instantiate objects of it directly; it’s only meant to be inherited from.
Now, let’s walk through common instantiation scenarios and their differences:
Scenario 1: Instantiating a Concrete Base Class Object
If your class A only has regular virtual functions (no pure ones), you can create an object directly:
A objA; objA.m1(); // Calls A's m1()—straightforward, no surprises
Since objA is a concrete instance of A, it uses A’s methods unless you override them in a derived class.
Scenario 2: Base Class Pointer/Reference to Derived Object
This is where virtual functions show their power. Suppose you have a derived class B that overrides m1():
class B : public A { public: void m1() override { cout << "this is B's m1() method" << endl; } }; // Using a heap-allocated pointer A* ptr = new B(); ptr->m1(); // Calls B's m1()—dynamic dispatch kicks in! // Using a stack-allocated reference B objB; A& ref = objB; ref.m1(); // Also calls B's m1()
Without the virtual keyword on A::m1(), this would call A’s m1() instead—because it would use static (compile-time) binding rather than dynamic (runtime) binding.
Scenario 3: Trying to Instantiate an Abstract Class
If A had a pure virtual function (say, virtual void m2() = 0;), these lines would throw compile errors:
A objA; // Error: cannot instantiate abstract class A* ptr = new A(); // Also error!
Abstract classes exist only to be inherited from—you have to create a derived class that implements all pure virtual functions before you can instantiate anything.
Why Your m3() Method Behaves Differently
In your code, m3() isn’t marked as virtual. So even if a derived class overrides it, calling it via a base pointer/reference will still use the base class’s version:
class B : public A { public: void m3() { cout << "this is B's m3() method" << endl; } }; A* ptr = new B(); ptr->m3(); // Calls A's m3()—no virtual = static binding
Only virtual functions get the dynamic dispatch magic that picks the right method based on the object’s actual type.
If you had a specific instantiation case in your cut-off code that’s still confusing—like stack vs heap allocation quirks—feel free to share more details and I’ll dive deeper!
内容的提问来源于stack exchange,提问作者Js_zero

