使用此技巧从外部访问受保护的成员,但这有效吗
Accessing protected members from outside with this trick, but is this valid?
如果我有以下类:
class Foo
{
protected:
int i;
public:
Foo() : i(42) {}
};
当然,我不能从外部访问受保护的成员,但我可以做这个小技巧:首先,我创建一个继承Foo:的新类
class Foo2 : public Foo
{
public:
int GetI() { return i; }
};
现在,每当我有Foo的实例或指向该实例的指针时,我都可以通过强制转换访问受保护的成员(因为我不使用任何其他成员(:
Foo *f = new Foo();
Foo f2;
std::cout << ((Foo2*)f)->GetI() << std::endl;
std::cout << (reinterpret_cast<Foo2&>(f2)).GetI() << std::endl;
我理解为什么这样做有效,但会有什么不好的后果吗?编译器不介意,并没有任何运行时检查。
reinterpret_cast<Foo2&>(f2)).GetI()
从技术上讲,这是未定义的行为。因此,它可能会工作,但不是必须的。
您正在将Foo
对象向下转换为Foo2
对象。
下转换是从基类转换为派生自基类。只有当对象在运行时寻址时,下转换才是安全的实际上是在寻址派生类对象
为了保护您的代码,您必须使用dynamic_cast
来检查下变频是否有效。
不建议使用reinterpret_cast
进行下铸。使用static_cast
或dynamic_cast
。
在阅读大量文章时,许多人写道,不要像你那样使用向下投射。一个危险的例子是在Foo
中有一个virtual void GetI()
。
相关文章:
- 通过指针调用模板类成员函数 [为什么这是有效的 c++]?
- 如何使用包含内部类的类实例有效地从内部类访问成员?
- 有效地初始化 const std::vector 类成员
- 在C 中实现基于模板的可选类成员的最有效方法
- 如何有效地将浮点数别名为数组的命名成员和元素
- 相对于向量对象的两个成员,找到两个向量的相交的有效方法
- 使用大型数据集初始化类成员向量的最有效方法
- 类模板的成员函数有条件无效(隐式实例化有效;显式实例化失败)
- 为什么仅在返回通用类中的自定义类型时才有效constexpr成员函数
- 模板化类的模板化成员编译失败.VC++ 有效,但 G++ 失败
- 具有未初始化成员的结构的constexpr默认构造函数仅在模板化时有效
- 使用相同的参数名称和成员名称是否有效
- 类模板成员模板的成员模板的显式模板函数专用化有效吗
- 将没有成员的函子设置为类成员对象还是堆栈对象更有效
- 智能感知说错误:成员"Class::field"无法访问,但它仍然有效?为什么?
- 为类中有效的成员变量提供初始值
- 在派生类构造函数中复制继承的成员有效吗
- 返回+重置成员变量的最有效方法
- 在C++03中,在未赋值的上下文中使用表示非静态数据成员的id表达式有效吗
- 使用数组作为元组成员:有效的C++11元组声明