我想从具有const
说明符的类继承,如下所示:
class Property
{
int get() const;
void set(int a);
};
class ConstChild : public const Property
{
// Can never call A::set() with this class, even if
// the instantiation of this class is not const
};
class NonConstChild : public Property
{
// Can call both A::set() and A::get() depending on
// the constness of instantiation of this class
};
我的编译器显然在第二个类声明中给出了const
关键字的错误。理想情况下,我希望避免创建ReadOnlyProperty
将继承的新类ConstChild
。
我可以以某种方式使用const
关键字进行继承吗?
答案 0 :(得分:6)
稍后在继承树中引入可变性并适当地派生:
class Property
{
int get() const;
};
class MutableProperty : public Property {
{
void set(int a);
};
然后:
class ConstChild : public Property { ... };
class MutableChild : public MutableProperty { ... };
答案 1 :(得分:3)
我需要一个相关的问题,即:真正控制/突出某些类的mutable和const访问。 我用这个简单的可重用模板包装器做到了:
template <typename T>
class TAccessor : private T
{
public:
const T& Const() const { return *this; }
T& Mutable() { return *this; }
};
// Example of use:
template <typename T>
using MyVector = TAccessor<std::vector<T>>;
void main()
{
MyVector<int> vector;
vector.Mutable().push_back(10);
int x = vector.Const()[1];
...
}
答案 2 :(得分:1)
我想从具有const说明符“
的类继承
无论你想要多少都无关紧要。你不能。这不是有效的C ++。
我可以以某种方式使用const关键字进行继承吗?“
没有
答案 3 :(得分:0)
如果您创建const
成员函数set
,您将获得所需内容。
class Property
{
int get() const;
void set(int a);
};
class ConstChild : public Property
{
void set(int a) const {}
};
唯一需要注意的是,狡猾的用户可以通过以下方式规避您的意图:
ConstChild child;
child.set(10); // Not OK by the compiler
Property& base = child;
base.set(10); // OK by the compiler
答案 4 :(得分:0)
使用数据成员或私有基类而不是公共基类。
然后您可以控制对该成员的访问权限。
如果需要多态行为,可以将Property事物设置为抽象接口。
答案 5 :(得分:0)
您可以使用模板类和常量类型的专门化:
template<typename T> class base_property {
protected:
T value;
};
template<typename T> class property : public base_property<T> {
public:
const T& get()const { return value; }
void set(const T& v){ value = v; }
};
template<typename T> class property<const T> : public base_property<T> {
public:
const T& get()const { return value; }
};
class ConstChild : public property<const int>{ };
答案 6 :(得分:0)
我也有同样的需求,最终我得到了这种完全手动的方法:
class A
{
public:
void fooMutable(void) {}
void fooConst(void) const {}
};
class B : private A
{
public:
using A::fooConst;
const A& getParent(void) const
{
return *this;
}
};
void fooParent(const A&) {}
int main(void)
{
auto b = B{};
b.fooConst(); // Ok
b.fooMutable(); // Fail
fooParent(b); // Fail
fooParent(b.getParent()); // Ok
return 0;
}
请注意,using关键字不适用于重载const / mutable:
class A
{
public:
void foo(void) {}
void foo(void) const {}
};
class B : private A
{
public:
using A::foo; // Expose the const and the mutable version
};
要解决此问题,您可以自己重新定义函数并调用父函数:
class B : private A
{
public:
void foo(void) const
{
A::foo();
}
};
如果您要继承一个较大的层次结构,这可能会非常耗时,但是如果它用于一个不太大的类,那么它应该非常合理并且对用户来说很自然。
答案 7 :(得分:-1)
我有一个技巧,而不是一个干净的解决方案。
class ConstChild : private Property
{
operator const Property () { return *this; }
};
然后
ConstChild cc;
cc.set(10); // ERROR
cc().get();