在没有朋友的情况下为基类提供受保护的访问权限
Give protected access to base class without friend
我将首先解释我的情况。
我有一个基类,可以自动实现一种引用计数。 它允许我将 C 样式的init()
和free()
库调用包装到引用计数的 API 中。
template<typename T>
class Service {
public:
Service() {
if(s_count++ == 0) {
T::initialize();
}
}
~Service() {
if(--s_count == 0) {
T::terminate();
}
}
private:
static int s_count;
};
template<typename T>
int Service<T>::s_count = 0;
希望实现这些初始值设定项和终止符的类将从如下所示Service
派生:
class Test : public Service<Test> {
friend class Service<Test>;
private:
static void initialize() {
std::cout << "Initialized" << std::endl;
}
static void terminate() {
std::cout << "Terminated" << std::endl;
}
};
但是,声明很混乱,因为我必须继承和交朋友我的Service
类。 有没有办法允许基类自动访问派生类的受保护成员或私有成员? 如果没有,我不妨问一下是否有更好的方法来写我在这里所做的。
"有没有办法允许基类自动访问派生类的受保护成员或私有成员?"
基类无法正式访问派生类的私有/受保护成员。通常,基类的设计方式是它们不需要知道派生类的任何内容。因此,如果需要从基类访问派生类中的成员,则应重新考虑设计。
编辑(根据@RSahu提议的文章):-
尽管在某些情况下,从基类访问派生类的成员函数可能很有用。就像在两个进程之间共享对象一样。
#include <iostream>
using namespace std;
template<typename T>
class Service {
struct TT: T {
using T::initialize;
using T::terminate;
};
public:
Service() {
if(s_count++ == 0) {
TT::initialize();
}
}
~Service() {
if(--s_count == 0) {
TT::terminate();
}
}
private:
static int s_count;
};
class Test : public Service<Test> {
//friend class Service<Test>;
protected:
static void initialize() {
std::cout << "Initialized" << std::endl;
}
static void terminate() {
std::cout << "Terminated" << std::endl;
}
};
template<typename T>
int Service<T>::s_count = 0;
int main() {
Test t;
}
N.M. 将这些方法虚拟化的建议让我想到:它本身不会工作,但如果将服务与其管理分离,它会起作用:初始化不仅适用于该特定服务实例,它适用于所有实例,也许正因为如此,它首先不应该成为服务类的一部分。
如果将它们解耦,则可以使用派生服务管理器必须实现的虚拟方法创建服务管理器基类,如下所示:
#include <iostream>
class ServiceManager {
template <typename T>
friend class Service;
virtual void initialize() = 0;
virtual void terminate() = 0;
};
template <typename T>
class Service {
public:
Service() {
if (s_count++ == 0) {
s_manager.initialize();
}
}
~Service() {
if (--s_count == 0) {
s_manager.terminate();
}
}
private:
static int s_count;
static ServiceManager &&s_manager;
};
template <typename T>
int Service<T>::s_count = 0;
template <typename T>
ServiceManager &&Service<T>::s_manager = T();
class TestManager : public ServiceManager {
void initialize() {
std::cout << "Initialized" << std::endl;
}
void terminate() {
std::cout << "Terminated" << std::endl;
}
};
class Test : public Service<TestManager> {
};
如果您的编译器不支持这种&&
的使用(它有效C++11,但无效C++03),您仍然应该能够通过进行s_manager
ServiceManager &
而不使用临时T
来初始化它,或者只是使s_manager
具有类型 T
来轻松调整代码。前者更详细,后者允许T
不是从ServiceManager
派生的实现。
相关文章:
- C++:无法访问声明的受保护成员
- 继承和友元函数,从基类访问受保护的成员
- C++:为什么无法在派生类中访问受保护的构造函数?
- 如何从其他结构访问受保护的结构变量
- 相同的层次结构,访问基类的受保护成员时的行为不同
- 从模板化父类中的派生内部类访问受保护的成员变量
- 在使用受保护和继承时无法访问在类中声明的私有成员
- 有没有办法通过 main 函数访问受保护的矢量大小而无需将其转换为公共?
- 派生类无法访问基类的受保护成员
- 访问说明符(私有/公共/受保护)如何在内部工作(限制成员访问)?
- 如何将超类的受保护成员访问到其派生类. 如果已在派生类中声明了具有相同名称的函数?
- 无法从派生类型的作用域访问另一个实例的受保护成员
- 在派生类的构造函数初始化中无法访问受保护的函数
- 无法在赋值运算符中访问基类的受保护方法
- 为什么我无法使用受保护/私有继承访问派生实例中基类的受保护成员?
- 将对象强制转换为派生类以访问父类的受保护成员
- 无法访问派生类函数内的基类的受保护数据成员
- 为什么继承的受保护操作员=()有公共访问权限
- 访问派生类C++中的受保护成员
- 跨公共/受保护访问的基于const的函数重载