C++实例ProtectedorPrivate?
作为父类的设计者,您可能会犹豫是否应该为您的成员函数提供受保护的或私有的访问。然后,我们来看看下面这个例子:
1。无关类访问受保护成员
# include
a类
protected:
void b(){ printf("哎呀!\ n ");}
};
void f(A * A)
{
class A _ hack:public A
{
friend void f(A *);
};
static _ cast(a)-> b();
}
B类
{
public:
void f(A * A)
{
A类_ hack:public A
{
friend B;
};
static _ cast(a)-> b();
}
};
int main()
{
f(NULL);
B()。f(空);
}
虽然static_cast的结果是未定义的,但是编译器一般会优化A_hack 空的派生类。A_hack和A的内存布局是一样的。大测试注意:这里的static_cast通常是no-op,所以上面的代码在实际应用中几乎肯定会成功。对于一个恶意用户来说,他的目的已经达到了。
2。调用纯虚函数
class a
{
protected:
virtual void fun()= 0;
};
B类:public A
{
public:
B(){ Dummy();}
private:
void Dummy(){ Fun();}
};
C类:公共B
{
公共:
虚拟void Fun(){ }
};
你以为传说中的纯虚函数是不能调用的吗?想看看VC中的_purecall会做什么吗?试试上面的代码。
问题的根源在于父类将Fun声明为protected。虽然你不应该在ctor中调用虚函数,但是当你在ctor中调用Dummy的时候,你不一定会注意到Dummy会调用里面的虚函数,所以灾难就发生了
如果你只想让子类在虚函数中提供某些行为,那么就把这些函数声明为private
虽然上面的代码不符合标准,但至少说明你的用户可以利用你提供的受保护的权限来实现你不想给的东西。如果你觉得自己连private都不信任(比如万恶的#define private public,这当然违反了One Definition规则(ODR),所以结果是不可预知的),那么你就用PImpl来实现你的接口。
0条评论