仅授予派生类对基类数据成员/函数的 const 访问权限
Giving derived class only const access to base class data members/functions
在我的特定情况下,我有一个基类"Base",带有一个数据成员"A_var"。我希望任何派生类都只能以与"Base"类在语法上相同的方式访问该数据成员。
如果它是受保护的或私有的,则派生类分别具有完全访问权限或没有访问权限。我可以将其设为私有,并创建一个返回 const 引用的受保护函数,但随后访问将在语法上有所不同。
class Base {
protected:
const type_t& A() const {return A_var;}
private:
type_t A_var;
void f();
};
class Derived : public Base{
public:
void g();
};
//access in Base class
void Base::f() {
type_t value = A_var;
A_var = value;
}
//access in Derived class
void Derived::g() {
type_t value = A();
A() = value; //Error, const reference; good
}
重载"A()",如下所示,也不起作用,因为"派生"类调用私有非常量"A()"。
protected:
const type_t& A() const {return A_var;}
private:
type_t& A() {return A_var;}
微小的差异可能看起来没什么大不了的,但在我的代码中,有各种宏从访问该数据成员开始。因此,我必须为"Base"类和派生类使用不同的宏,这会破坏代码的读取和写入流。
更新:澄清一下,问题是在语法上使派生类和基类中的访问相同。也就是说,例如,我可以调用一个函数 f(),并让它在基类中调用时返回一个非常量引用,但在派生类中调用时返回一个常量引用。动机是使派生类中的强制 const 访问无缝。我意识到可能没有办法做到这一点,但我问以防万一。
更新:为了提供一个真实的例子(有 2-3 个这样的情况),这在代码中被大量使用:
test_files_var.current()->current_test()
我用
#define TEST() test_files_var.current()->current_test()
因为派生类将通过不同的函数/成员访问test_files_var
,即 testFiles()
,我必须对TEST()
有第二个定义,即 DTEST()
.问题更多地取决于"宏"的使用次数,而不是它们的数量。
哪里没有简单的内置解决方案。但是一点模板魔术可能会起到一个作用:
template <class NonConst>
struct Matcher {
template <class AnyOther>
static const AnyOther &get(AnyOther &obj) { return obj; }
static NonConst &get(NonConst &obj) { return obj; }
};
class Base {
public:
Base() : a_(42) { }
public:
virtual void Fun() {
Matcher<Base>::get(*this).A();
}
const int &A() const {
std::cout << "const" << std::endl;
return a_;
}
int &A() {
std::cout << "no const" << std::endl;
return a_;
}
private:
int a_;
};
class Derived : public Base {
public:
void Fun() {
Matcher<Base>::get(*this).A();
}
};
int main(int argc, const char * argv[]) {
Derived d;
d.Fun();
Base b;
b.Fun();
return 0;
}
上面的代码将输出:const no const
.
因此,在这两个Fun
函数中,您基本上具有相同的访问模式,如果需要,您可以将其包装在宏中。
如果我正确理解您的问题,您希望授予对派生类的访问权限访问基类的私有变量的权限,但只能使用。
在这种情况下,您只需定义一个受保护的常量引用变量并将其初始化为私有变量:
class Base {
public:
Base() : cA(A_var) { ... } // to be completed with rule of 3
protected:
const type_t& cA;
private:
type_t A_var;
void f();
};
派生类中的访问随后使用常量引用:
//access in Derived class
void Derived::g() {
type_t value = cA;
//cA = value; //Error, const reference: can't assign
}
现场演示
您可以将基类更改为
class Base {
public:
Base() : A_cref(A_var) {}
private:
type_t A_var;
void f();
protected:
const type_t& A_cref;
};
具有额外的成员开销。
如果宏可从派生类中使用,则它们只需要 const 访问 - 因此宏可以使用受保护的 const 访问函数。
要修改变量的宏必须使用私有变量,并且只能在基类中使用。
TEST()
宏替换为基类中的公共函数test()
,您的问题似乎会消失:
class Base
{
public:
void test() { test_files_var.current()->current_test() }
private:
type_t test_files_var;
};
- 为什么这个函数将"const char*"转换为"void* const"而不是"const void*"
- 从函数返回const char*数组
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 在 const 函数中通过引用和指针返回之间的区别
- 使用 std::string () const 函数启动线程或未来
- 在运算符重载定义中使用成员函数(const错误)
- 使用共享指针的函数调用,其对象应为 const
- 将函数参数"const char*"转换为"std::string_view"是
- 为什么返回类型的'const'限定符对标有 __forceinline/内联的函数没有影响?
- 使用按引用调用时,不能在没有对象的情况下调用成员函数 const
- 在呼叫运算符函数const中调用运算符时错误
- 我需要用c ++ 98重写c ++ 11代码,c ++ 11正在使用lambda函数[&](const Output & o
- 函数 const 本地对象在C++会发生什么
- int const函数(参数)、int函数(const参数)和int函数(parameters)const之间的区别是什
- const_cast为函数const设置规则并破坏规则
- 构造函数"const variables"设置的用于表示C++数组的边界?
- 将char**传递给C++中的函数(const char**)
- 复制构造函数const char*和Shared_ptr
- 使函数"const"的意图是什么
- c++嵌套映射不匹配成员函数const成员