访问控制说明符(public
和protected
)private
不适用于成员函数或数据成员。它们适用于成员函数和数据成员名称。那行得通。如果您可以引用不带名称的成员,则可以访问它。
这正是这里发生的事情。您正在调用B::someMethod
,但您使用的A::someMethod
是公开的 name 来调用它。没问题。
您建议不应从类外部调用私有成员函数(暂时不考虑朋友)。在以下情况下,您想要的语义将如何工作?
共享库hider
:
hider.h
:
typedef void (*FuncType)();
class Hider {
private:
static void privFunc();
public:
static void pubFunc();
FuncType getFunction() const;
};
hider.cpp
#include <cstdlib>
#include <iostream>
#include "hider.h"
void Hider::privFunc() {
std::cout << "Private\n";
}
void Hider::pubFunc() {
std::cout << "Public\n";
}
FuncType Hider::getFunction() const {
if (std::rand() % 2) {
return &pubFunc;
} else {
return &privFunc;
}
}
使用库的应用程序hider
#include "hider.hpp"
int main()
{
Hider h;
FuncType f = h.getFunc();
f();
}
来电f()
呢?它是否应该在运行时以某种形式在 50% 的时间内失败access control violation
?
正如 DyP 在评论中所建议的,更现实的场景是众所周知的“模板方法”设计模式:
class Container
{
public:
void insert(const Item &item) {
preInsert();
data.insert(item);
postInsert();
}
private:
std::vector<Item> data;
virtual void preInsert() = 0;
virtual void postInsert() = 0;
};
class ThreadSafeContainer : public Container
{
private:
std::mutex m;
virtual void preInsert() {
m.lock();
}
virtual void postInsert() {
m.unlock();
}
};
您的语义将意味着此代码无法编译。