从嵌套结构调用受保护的基类函数
Call a protected base class function from nested struct
通常嵌套结构可以访问拥有类public
、protected
和public
成员函数。从嵌套结构中调用基类的 protected
成员函数也没有问题,即以下代码可以正确编译和工作:
#include <iostream>
class Base
{
public:
Base()
{}
protected:
void baseProtectedFunc()
{
std::cout << __func__ << "Called for Basen";
}
};
class Derived : public Base
{
public:
explicit Derived() : Base()
{}
void accessBaseProtectedFuncFromNested()
{
Nested myNested( this );
myNested();
}
private:
struct Nested
{
explicit Nested( Derived* ptr ) : derived_( ptr )
{}
void operator()()
{
derived_->baseProtectedFunc();
}
Derived* derived_;
};
};
int main( int, char** )
{
Derived myDerived;
myDerived.accessBaseProtectedFuncFromNested();
return 0;
}
现在,请考虑以下代码,该代码使用 mpl::inherit_linearly
生成派生的基类,使用mpl::vector
类型:
#include <iostream>
#include <typeinfo>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/inherit.hpp>
#include <boost/mpl/inherit_linearly.hpp>
#include <boost/mpl/for_each.hpp>
template<typename T>
class Base
{
public:
Base()
{}
protected:
void baseProtectedFunc()
{
std::cout << __func__ << "Called for Base< " << typeid(T).name() << " >n";
}
};
typedef boost::mpl::vector< long
, unsigned
, bool
, std::string
> parameter_type_list_t;
typedef boost::mpl::inherit_linearly< parameter_type_list_t
, boost::mpl::inherit< boost::mpl::_1
, Base< boost::mpl::_2 > >
>::type base_types;
class Derived : public base_types
{
public:
explicit Derived() : base_types()
{}
template<typename T>
void accessBaseProtectedFuncFromNested()
{
Nested myNested( this );
myNested.someFunc<T>();
}
private:
struct Nested
{
explicit Nested( Derived* ptr ) : derived_( ptr )
{}
template< typename T >
void someFunc()
{
Base<T>* base = static_cast<Base<T>*>( derived_ );
base->baseProtectedFunc();
}
Derived* derived_;
};
};
int main( int, char** )
{
Derived myDerived;
myDerived.accessBaseProtectedFuncFromNested<unsigned>();
return 0;
}
使用 GCC 版本 4.4.6-3(在 c++03 和 c++0x 模式下),将生成以下错误:
friend-prot.cpp: In member function ‘void Derived::Nested::someFunc() [with T = unsigned int]’:
friend-prot.cpp:47: instantiated from ‘void Derived::accessBaseProtectedFuncFromNested() [with T = unsigned int]’
friend-prot.cpp:82: instantiated from here
friend-prot.cpp:17: error: ‘void Base<T>::baseProtectedFunc() [with T = unsigned int]’ is protected
friend-prot.cpp:72: error: within this context
如果我使我尝试调用的函数public
代码将按预期编译和工作。
我可以通过向派生添加一个额外的 private
成员函数来解决这个问题,该函数只是转发来自 Nested 的调用,即:
struct Nested
{
explicit Nested( Derived* ptr ) : derived_( ptr )
{}
template< typename T >
void operator()()
{
derived_->forwarder<T>();
}
Derived* derived_;
};
template< typename T >
void forwarder()
{
Base<T>::baseProtectedFunc();
}
我不明白为什么我不能调用baseProtectedFunc()
,如果在使用mpl::inherit
时protected
。
为什么允许我在第一个示例中调用基类保护函数,而在第二个示例中则不允许?
你会发现
,如果你把转发函数写成
template <typename T>
void forwarder()
{
Base<T>* base = static_cast<Base<T>*>( derived_ );
base->baseProtectedFunc();
}
问题在于,强制转换为基指针会掩盖编译器实际上可以使用指定指针从当前上下文访问baseProtectedFunc
的事实。由于这一点被掩盖了,编译器必须假设不允许通过该指针进行访问。
由于您在转发函数中使用的语法也可以从嵌套类中使用,因此解决方案相当简单和优雅:
struct Nested
{
explicit Nested( Derived* ptr ) : derived_( ptr )
{}
template< typename T >
void someFunc()
{
derived_->Base<T>::baseProtectedFunc(); /* <-- Changed */
}
Derived* derived_;
};
相关文章:
- C++ 继承:将子类传递给需要基类的函数并获取子类行为
- 将自定义函数传递到基抽象类中以延迟执行
- 调用原子的 store() 时可以调用基类型类的函数吗?C++
- C++17 使用驱动类常量作为基类构造函数的参数来初始化基类构造函数
- 派生类(构造函数具有参数)和基类(构造函数缺少参数)之间没有可行的转换
- 如何将子类作为函数的参数传递给期望基类,然后将该对象传递到指向这些抽象类对象的指针向量中?
- 从基类调用函数的多态性
- 在成员构造函数之后调用基类构造函数
- 在C++单元测试上下文中,抽象基类是否应将其他抽象基类作为函数参数
- 如何在将原始指针移动到基类构造函数之前从unique_ptr中提取原始指针
- 如何在具有相同函数名称的派生类中调用基类的函数
- 我不能访问基类的函数
- 根据模板参数引用不同基类的函数
- 在基/派生类中调用C++的纯虚函数
- C++ 模板化基类的函数模板专用化
- 如果基类指针无法访问派生类成员函数,那么多态性有什么方便的呢?
- 如何在C++中调用基类虚函数
- 指向从指针派生类成员函数的指针,指向基类成员函数
- C++:在共享对象中调用抽象基类构造函数/未定义的符号
- 如何在 C++ 中将参数传递给基类构造函数