C++ 智能指针与哑指针:多态行为古怪

C++ 智能指针与哑指针:多态行为古怪,c++,pointers,c++11,polymorphism,smart-pointers,C++,Pointers,C++11,Polymorphism,Smart Pointers,我在调试一些较大代码中的一个问题,并意识到智能指针及其多态属性有些奇怪。通过一个简单的例子可以很好地看出这一点: #include <iostream> #include <memory> using namespace std; class A { public: virtual void who() {cout << "I am class A" << endl; }; }; class B : public A{ public:

我在调试一些较大代码中的一个问题,并意识到智能指针及其多态属性有些奇怪。通过一个简单的例子可以很好地看出这一点:

#include <iostream>
#include <memory>

using namespace std;

class A {
public:
  virtual void who() {cout << "I am class A" << endl; };
}; 

class B : public A{
public:
  void who() {cout << "I am class B" << endl; };
}; 

int main(int argc, char *argv[])
{
  B b;  
  A * aptr = &b;
  aptr->who(); //Output: I am class B

  B * bptr = &b;
  bptr->who(); //Output: I am class B

  shared_ptr<A> sptr;
  sptr = make_shared<A>(b);
  sptr->who(); //Output: I am class A

  sptr = make_shared<B>(b);
  sptr->who(); //Output: I am class B

  return 0;
}
#包括
#包括
使用名称空间std;
甲级{
公众:
虚拟void who(){cout who();//输出:我是B类
返回0;
}
前两个输出对我来说很有意义,但是当我初始化的唯一对象是类型B时,为什么我可以访问A中定义的成员函数(参见第三个输出)?从某种意义上说,这是访问派生类型对象基类成员的一个很好的技巧。然而,这对我来说仍然有点可怕


有人能解释为什么智能指针可以出现这种行为,而不是常规指针吗?

下面的陈述:

sptr = make_shared<A>(b);

您不是从指向
B
的指针创建共享的\u ptr,而是使用
a
的复制构造函数创建一个新的
a
对象使用
b
构造类型为
A
的对象,并指向新构造的对象。这将
b
对象切片,因此
shared\u ptr
真正指向
A

std::make\u shared
始终创建一个全新的对象。也就是说

sptr = make_shared<A>(b);
而且不像

A* p2 = &b;

p1
make_shared
的返回值根本不指向
b

aptr->who();
行应该是
bptr->who();
如果您确实想“访问派生类型对象的基类成员”,您只需执行
sptr->A::who())
。修复了那个打字错误,谢谢!啊。这很有道理。毕竟没那么可怕!
A* p1 = new A(b);
A* p2 = &b;