gpt4 book ai didi

c++ - 从基类指针调用 C++ 中的私有(private)函数

转载 作者:太空狗 更新时间:2023-10-29 21:11:03 25 4
gpt4 key购买 nike

让我们从类 A 派生一个类 B
B 有一个私有(private)成员 void secret()A 有一个公共(public)的 virtual void secret()

B obj;
A* ptr = &obj;
ptr->secret(); //calls the private function secret in class B.

现在,以下代码成功运行。这不是很糟糕吗? vtable 不应该也关心底层函数是否可访问吗?

这里是 the source code有更多细节和很好的例子。
这是 my youtube video谈论同样的事情。

最佳答案

首先,它是合法的——因为 vtable 不参与表示调用期间的访问——作为 C++ 标准 [class.access.virt]说:

Access is checked at the call point using the type of the expression used to denote the object for which the member function is called (B* in the example above). The access of the member function in the class in which it was defined (D in the example above) is in general not known.

也就是说,SOLID principles被认为是良好代码设计的支柱。 SOLID 中的“L”代表 Liskov Substitution Principle ,据此:

if S is a subtype of T, then objects of type T may be replaced with objects of type S (i.e. an object of type T may be substituted with any object of a subtype S) without altering any of the desirable properties of the program.

所以你看,通过改变访问权限,比方说基类中的公共(public)成员,我们无疑会改变这个类型 S 的派生对象的接口(interface),当试图将它用作 T 时。因此限制了它的使用程序的其他部分,从而改变其属性,从而打破 Liskov 原则

此外,C++ 常见问题解答 According to which this hiding of derived members (virtual or not) usually indicates bad practice 是此类使用和设计问题的综合权威。 :

Should I hide member functions that were public in my base class?
Never, never, never do this. Never. Never!

对于狂热的读者: C++ FAQ 说 the following about virtual methods:

there really are two different basic ways to use virtual functions:

Suppose you [...] you have a method whose overall structure is the same for each derived class, but has little pieces that are different in each derived class. So the algorithm is the same, but the primitives are different. In this case you’d write the overall algorithm in the base class as a public method (that’s sometimes non-virtual), and you’d write the little pieces in the derived classes. The little pieces would be declared in the base class (they’re often protected, they’re often pure virtual, and they’re certainly virtual), and they’d ultimately be defined in each derived class. The most critical question in this situation is whether or not the public method containing the overall algorithm should be virtual. The answer is to make it virtual if you think that some derived class might need to override it.

Suppose you have the exact opposite situation [...], where you have a method whose overall structure is different in each derived class, yet it has little pieces that are the same in most (if not all) derived classes. In this case you’d put the overall algorithm in a public virtual that’s ultimately defined in the derived classes, and the little pieces of common code can be written once (to avoid code duplication) and stashed somewhere (anywhere!). A common place to stash the little pieces is in the protected part of the base class, but that’s not necessary and it might not even be best. Just find a place to stash them and you’ll be fine. Note that if you do stash them in the base class, you should normally make them protected, since normally they do things that public users don’t need/want to do. Assuming they’re protected, they probably shouldn’t be virtual: if the derived class doesn’t like the behavior in one of them, it doesn’t have to call that method.

因此,在虚拟化的任何一个用例中,这里都没有提到派生类中虚拟成员访问的更改。因此,我也认为这种策略没有已知的良好用法

关于c++ - 从基类指针调用 C++ 中的私有(private)函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51874414/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com