【问题标题】:Passing const object by reference issue通过引用传递 const 对象问题
【发布时间】:2012-09-06 15:27:08
【问题描述】:

假设我们有以下代码:

#include <iostream>

class Person{
public:
    Person(int age);
    int get_a();
private:
    int a;
};

Person::Person(int age)
{
    a = age;
}

int Person::get_a()
{
    return a;
}

void Show_Age(Person P)
{
    std::cout<<P.get_a()<<std::endl;
}

int main() {

    Person P(10);
    Show_Age(P);
    return 0;
}

现在假设我们有一个重的对象,我们应该通过引用传递 Person,所以我们继续:

void Show_Age(Person &P)
{
    std::cout<<P.get_a()<<std::endl;
}

没有问题,但一个很好的观察是 P 应该是 const,我们尝试一下:

void Show_Age(const Person &P)
{
    std::cout<<P.get_a()<<std::endl;
}

编译器失败:

error: passing ‘const Person’ as ‘this’ argument of ‘int Person::get_a()’ discards qualifiers [-fpermissive]

如何解决?

【问题讨论】:

  • 为什么不将Show_Age 设为成员函数?
  • 因为它是一个测试函数,实际上我还有另一个类和一个使用get函数的函数,所以在类里面我有一个向量,所以我需要通过引用传递一个对象。

标签: c++ parameter-passing


【解决方案1】:

const 正确性是病毒式的,你应该从内而外开始(即每个类都应该将不修改对象的成员函数标记为const,允许调用者在 const 对象(或引用)上使用它们到 const 对象)。

【讨论】:

  • 谢谢,这是个好建议。让我看看,你是在建议我:我应该有重载的 get 函数以允许该类的用户按照他们的意愿正确使用该类?
  • @facunvd:从更一般的意义上说,我们不是在谈论重载,而是在谈论每个函数。一个不修改对象状态的函数应该是const(它 const,但你应该这样标记它)。添加const 关键字意味着编译器和你一样知道:get_a 不会修改对象。没有它,编译器将不知道它,并且不允许您在 const 对象上调用该函数。
【解决方案2】:

您还必须将Person::get_a 标记为常量:

class Person
{
    // ...

    int get_a() const;

    // ...
};

这告诉编译器get_a 不会修改对象。

【讨论】:

    【解决方案3】:

    您应该标记get_a const 以便编译:

    class Person{
    public:
        Person(int age);
        int get_a() const;
    private:
        int a;
    };
    
    int Person::get_a() const
    {
        return a;
    }
    

    这样做告诉编译器成员函数不会修改对象的状态,使其与const指针和引用兼容。

    【讨论】:

      猜你喜欢
      • 2012-07-07
      • 2013-11-24
      • 1970-01-01
      • 2012-06-14
      • 1970-01-01
      • 2021-06-04
      • 1970-01-01
      • 1970-01-01
      • 2017-09-11
      相关资源
      最近更新 更多