是否可以同时声明一个类成员的常量/非常量?
Is it possible to declare a class member both const/non-const?
我有一个类,它可以将非常量指针或常量指针作为其重载构造函数的参数。在我的特殊情况下,我需要从类T
的const
和non-const
方法实例化此类的对象,但它从 const 方法失败,因为它无法将 const 指针分配给foo
。
myClass() {
public:
myClass(T* v);
myClass(const T* v);
// ...
T* foo;
// ...
}
是否可以将两个构造函数中的参数分配给foo
?如果是这样,正确的语法是什么?
编辑:
在更具体的情况下,我有一个类myClass
,它环绕std::vector
并允许我通过嵌套类mySubset
直接访问向量的子集:
template<typename _type>
myClass() {
std::vector<_type> data;
public:
class mySubset(){
myClass<type>* foo;
public:
mySubset(myClass<_type>* _in) { foo = _in; };
mySubset(const myClass<_type>* _in) { foo = _in; /* error */ };
// ...
}
// ...
myClass();
// ...
void mySubset method() { return mySubset(this); };;
void mySubset const_method const() { return mySubset(this); /* error */ };
// ...
}
其中的代码是无关紧要的 - 基本上mySubset
允许读取和写入特定的向量位置。虽然我能够通过单独的 const 和非 const 嵌套类实现我想要的东西,但我正在寻找一种使用单个返回类型来实现这一点的方法。
我认为你必须重新考虑你的设计,因为你不能用const T*
的左值初始化一个T*
,没有const_cast
应该避免,除非你真的确定,(因为如果你试图在丢弃常量后修改常量指针,它会调用一个未定义的行为)
相反,您可以使用模板类型推断来const
和non const
template <typename T>
class myClass {
public:
//myClass(T* v):foo(v) { }
myClass( T* v):foo(v)
{
}
// ...
T* foo;
// ...
};
然后
int a =42;
const int* p1 = &a;
int *p2 = &a;
myClass X1(p1); //C++17 auto type deduction or use myClass<const int> X1(p1)
myClass X2(p2);
您可以在const T*
构造函数中使用const_cast
,但通常不应该使用。
const T*
表示"指向常量值 T",并且您存储"指向 T 的指针"。 如果你执行 const 强制转换,你最终可能会修改一个不应该修改的值。 如果你不打算修改foo
,只需const T*
声明它,只使用单个const T*
构造函数。
我会检查一下这是否是设计问题。 很多时候会出现这些场景: (1) 你在哪里存储一个指向非常量的东西的指针,而它应该是常量。 通常,这是因为您正在访问另一个对象中的值,并且您应该在每个使用站点上将该对象作为(可能是 consst)引用传递,而不是存储指向它的指针。 (2)当你真的想存储一个对象的副本时,在这种情况下,你只需保留一个常规T
并将其作为构造函数中的const T&
传入。 (3) 您正在处理原始的 C 样式字符串,并希望将内容复制到您自己的缓冲区中。
如果您不想使用参数化类型(模板)类作为@P0W的答案,则不可能仅使用一个指针来接受所有常量和非常量指针类型。您需要另一个常量指针类型才能仅接受包装类中的const <your another class> *
。 下面的代码在包装类中有两个单独的指针类型后工作,你可能不喜欢。
#include <iostream>
using namespace std;
class SomeObject {
public:
SomeObject(){}
explicit SomeObject(int i):testVal(i){}
private:
int testVal;
};
class PtWrapper {
public:
PtWrapper(SomeObject *pso);
PtWrapper(const SomeObject *cpso);
private:
SomeObject *pSO;
const SomeObject *cpSO;
};
int main(int argc, char *argv[]) {
SomeObject so(133);
SomeObject *pso = &so;
const SomeObject cso(166);
const SomeObject *cpso = &cso;
PtWrapper pw1(pso);
PtWrapper pw2(cpso);
return 0;
}
PtWrapper::PtWrapper(SomeObject *pso) :pSO(pso){
}
PtWrapper::PtWrapper(const SomeObject *cpso):cpSO(cpso){}
- 私有类型的静态常量成员
- constexpr构造函数需要常量成员函数时出现问题
- Clang 格式 10.0 与 5.0 常量成员函数的格式不同
- 为什么"具有常量成员的结构"类型的指针不能指向"具有非常量成员的结构"?
- 常量成员函数中成员变量的类型
- 如何处理运算符=中的常量成员?
- 常量成员和没有setter的私有成员之间有什么区别
- C++:允许临时对象调用非常量成员函数的设计理念是什么?
- 移动具有常量成员的类的构造和分配
- ARM C++编译器不会编译具有可变常量成员的结构
- 强制在编译时计算类的类的常量成员
- 类中常量成员函数的 c++ 链接错误
- 为什么常量成员可以初始化两次?
- 专用常量成员函数的成员检测
- 与其他静态const成员初始化静态常量成员
- 具有静态和常量成员变量的对象
- 结构中的常量成员即使在初始化后也返回 0
- 在非常量成员函数中,为什么点这个非常量,而 decltype 指针这是常量
- 有没有一种通用方法来"unprotect"静态常量成员?
- 如何初始化共享复杂初始化代码的多个常量成员变量?