面试题答案
一键面试可能出现的访问权限问题
shared_from_this
访问权限:std::enable_shared_from_this
提供了一种从对象内部获取std::shared_ptr
的机制。在模板元编程环境下,由于模板参数T
的多样性,可能会出现shared_from_this
调用权限问题。例如,如果Final
类的成员函数试图调用shared_from_this
,可能因为继承层次和访问权限的设置不当,导致无法正确获取shared_ptr
。因为std::enable_shared_from_this
依赖对象必须由std::shared_ptr
管理,否则调用shared_from_this
会导致未定义行为。- 虚基类成员访问权限:在多层次的虚基类继承体系中,不同派生类对虚基类成员的访问权限可能因为模板实例化而变得复杂。比如,
Derived1
和Derived2
从Base
继承时,若Base
中的成员有不同的访问修饰符(public
、protected
、private
),在Final
类中访问这些成员时,可能由于模板实例化的特性,导致编译器对访问权限判断错误。例如,如果Base
中有一个protected
成员,在Final
类中试图以错误的访问方式访问,编译器可能无法在模板实例化期间正确捕获这个错误。
解决方案
shared_from_this
问题解决方案:- 确保所有使用
shared_from_this
的对象都由std::shared_ptr
管理。在创建对象时,应使用std::make_shared
或通过std::shared_ptr
构造函数来初始化对象。例如,在创建Final
对象时:
std::shared_ptr<Final<int>> finalObj = std::make_shared<Final<int>>();
- 对于模板类中调用
shared_from_this
的成员函数,确保这些函数在对象由std::shared_ptr
管理的前提下调用。可以在函数内部添加一些运行时检查,比如:
template <typename T> class Final : public Derived1<T>, public Derived2<T> { public: std::shared_ptr<Final<T>> getSharedPtr() { if (auto p = shared_from_this().lock()) { return std::static_pointer_cast<Final<T>>(p); } return nullptr; } };
- 确保所有使用
- 虚基类成员访问权限问题解决方案:
- 仔细设计虚基类
Base
中成员的访问修饰符。对于希望在整个继承体系中广泛访问的成员,设置为public
;对于只希望在派生类内部访问的成员,设置为protected
;对于仅在Base
类内部使用的成员,设置为private
。 - 在模板类定义时,遵循 C++ 的访问权限规则。例如,在
Derived1
和Derived2
中,若Base
的成员是protected
,则在这两个派生类中,这些成员保持protected
访问权限。在Final
类中,若要访问Base
的protected
成员,必须通过派生类的接口函数,而不能直接访问。比如:
template <typename T> class Base : virtual public std::enable_shared_from_this<Base<T>> { protected: T data; }; template <typename T> class Derived1 : public Base<T> { public: T getData() const { return this->data; } }; template <typename T> class Final : public Derived1<T>, public Derived2<T> { public: T accessBaseData() { return this->Derived1<T>::getData(); } };
- 仔细设计虚基类
通过上述设计,可以在模板实例化过程中,确保不同层次的虚基类继承访问权限能够正确处理。