【问题标题】:invalid conversion from ‘const type*’ to ‘type*’从‘const type*’到‘type*’的无效转换
【发布时间】:2015-10-21 13:52:24
【问题描述】:

我想通过一个类的构造函数存储一个指向另一个类的对象的指针。这样做的正确方法是什么?

如果我将MyClass1* ptr 替换为const MyClass1* ptr,则没有错误,但在这种情况下,我认为我不能再更改ptr。实现我想要的正确方法是什么?

example.cpp

class MyClass1{
    public:
        int a;
        int b;
};

class MyClass2{
    MyClass1* ptr;
    public:
        MyClass2(const MyClass1& obj){ptr = &obj;};
};

int main(int argc, char* argv[]){
    MyClass1 object1;
    object1.a = object1.b = 0;
    MyClass2 object2(object1);
    
    return 0;
}

编译通过g++ -o example example.cpp给我这个错误

example.cpp:在构造函数'MyClass2::MyClass2(const MyClass1&)'中:

example.cpp:10:37: 错误:从‘const MyClass1*’到‘MyClass1*’的无效转换[-fpermissive]

MyClass2(const MyClass1& obj){ptr = &obj;};

【问题讨论】:

  • 为什么不删除 obj 参数的 const 修饰符?你也可以直接传递指针而不是引用。
  • @aslg:因为我不希望构造函数可以修改对象。 (我知道没有任何东西可以实际修改该对象)
  • @giusva 但是如果你想在你的实例中存储一个可修改的指针,你不能给它传递一个 const 指针。你不能两全其美。构造函数最终是属于您的类的函数。它可以对成员数据以及任何其他成员函数进行操作,即使您在特定情况下不希望这样做。
  • @giusva 你是对的,如果只看你问什么,这并不是真正的重复。但是这个问题与您的基本问题/潜在问题相匹配:“const MyClass1 *”中的 const 是什么。

标签: c++ pointers reference constants


【解决方案1】:

如果你想改变ptr指向的东西,那么你的函数需要通过非const引用来获取它的参数(因为MyClass2可能会修改它):

MyClass2(MyClass1& obj) { ptr = &obj; }

或者,如果您不打算修改ptr 指向的东西,那么应该将ptr 声明为指向const 的指针:

const MyClass1* ptr;

这两种解决方案都会导致代码编译。

【讨论】:

  • const MyClass1& 不安全,因为可以传入一个临时的
  • 这也是不安全的,因为可能会传入一个生命周期短于 Class2 对象的非临时对象。通常,长时间存储非拥有引用/指针是要求麻烦,因为这些终身问题。
  • @zenith:在我的算法中,Class1 的对象比Class2 具有指向第一个对象的对象的生命周期更长。然而,这显然不是一般情况。我该如何考虑这种情况?
  • @giusva 你不能。但是您可以使用shared_ptr 来共享所有权并使对象保持活动状态。
  • 在 C++ 中,编译器中没有机制可以检查您是否正确管理引用对象的生命周期(例如在 Rust 中)。在这方面你是靠自己的。尽管您始终可以选择通过使用 CoffeeandCode 提到的shared_ptr 将引用对象的所有权共享给ptr 来绕过它,这会强制引用对象保持活动状态,只要有一些shared_ptr 指向它.
【解决方案2】:

根据最后几个 cmets 回答。

我会给你一个例子,将 const 应用于带有 int 的指针,

int a = 2;
int b = 3;

int*              p1 = &a; // Modifiable pointer  modifiable value
const int*        p2 = &a; // Modifiable pointer  const value
int* const        p3 = &a; // Const pointer       modifiable value
const int * const p4 = &a; // Const pointer       const value

*p1 = 3; // Ok, modifiable left-value
*p2 = 4; // Error: non-modifiable left-value
*p3 = 5; // Ok
*p4 = 6; // Error

p1 = &b; // Ok: modifiable pointer
p2 = &b; // Ok
p3 = &b; // Error
p4 = &b; // Error

在您的情况下,您正在寻找一个可修改的指针,但它是一个 const 值。所以你想要第二种情况,

const MyClass1* ptr;

(这是你最初拥有的)

看来您实际上并没有尝试更改指针?

【讨论】:

    【解决方案3】:

    我从评论中知道你要修改指针的内容,而不是指针指向的对象,所以请将ptr指针声明为const MyClass1* ptr。这意味着ptr 是一个指向const MyClass1 的指针。所以你可以改变指针,但是你不能修改指针所引用的对象。

    【讨论】:

      【解决方案4】:

      先去掉多余的;

      MyClass2(const MyClass1& obj){ptr = &obj;}
      

      不能在函数内部传递 const 参数(以后可能会修改它),所以这可能有效:

      MyClass2(MyClass1 & obj){
          ptr = &obj;
      }
      

      但这里 &obj 的值超出了本地范围。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-08-17
        • 2020-08-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-03
        相关资源
        最近更新 更多