如何修改user构造函数,让基类unique_ptr调用派生类Print方法?
问题解决方法
核心问题在于你的代码未启用C++的动态多态机制,导致调用Print时始终执行基类版本,和构造函数本身无关——构造函数里的对象转型逻辑是正确的,m_ptr确实指向了派生类对象。
必须的核心修改(实现多态的关键)
要让基类指针根据实际指向的对象类型调用对应函数,需要将基类的Print声明为虚函数,同时基类析构函数也需设为虚函数(避免派生类对象析构不完整):
template<class T> class Base { public: Base() {}; // 虚析构函数,确保派生类对象能正确析构 virtual ~Base() {}; // 声明为虚函数,启用动态绑定 virtual void Print() { std::cout << "Print from Base" << std::endl; } };
另外,在派生类的Print函数后可以添加override关键字(C++11及以上支持),明确表示这是对基类虚函数的重写,避免因签名不一致导致的隐性错误:
class Derived1: public Base<int> { public: Derived1() {} void Print() override { std::cout << "Print from Derived1" << std::endl; } }; class Derived2: public Base<int> { public: Derived2() {} void Print() override { std::cout << "Print from Derived2" << std::endl; } };
关于构造函数的补充说明
你原本的user(int type)构造函数逻辑完全正确,不需要修改。make_unique<Derived1>()创建的派生类对象可以安全赋值给unique_ptr<Base<int>>,这是合法的向上转型,指针会正确指向派生类实例。
最终完整代码
#include <iostream> #include "memory" using namespace std; template<class T> class Base { public: Base() {}; virtual ~Base() {}; virtual void Print() { std::cout << "Print from Base" << std::endl; } }; class Derived1: public Base<int> { public: Derived1() {} void Print() override { std::cout << "Print from Derived1" << std::endl; } }; class Derived2: public Base<int> { public: Derived2() {} void Print() override { std::cout << "Print from Derived2" << std::endl; } }; class user { public: user(); user(int type) :m_type(type) { switch(type) { case 1: m_ptr = make_unique<Derived1>(); break; case 2: m_ptr = make_unique<Derived2>(); break; default: break; } } ~user() {}; void UserPrint() { m_ptr->Print(); } private: std::unique_ptr<Base<int>> m_ptr; int m_type; }; int main() { user a(1); user b(2); a.UserPrint(); b.UserPrint(); return 0; }
运行后会得到预期输出:
Print from Derived1 Print from Derived2
内容的提问来源于stack exchange,提问作者Nick X Tsui
相关产品推荐
相关产品推荐

