简体   繁体   English

C ++-对const感到困惑

[英]C++ - confused about const

I am reading this tutorial about const objects http://www.learncpp.com/cpp-tutorial/810-const-class-objects-and-member-functions/ . 我正在阅读有关const对象的本教程http://www.learncpp.com/cpp-tutorial/810-const-class-objects-and-member-functions/

I understand const objects can only access const functions. 我了解const对象只能访问const函数。 What confuses me is when we pass a const object to a copy constructor, how can it access non-const functions? 令我困惑的是,当我们将const对象传递给副本构造函数时,它如何访问非const函数?

Example: 例:

class Dog {
     protected:
         string m_name;
         int m_age; 
     public:
         Dog() : m_name("Fido"), m_breed("Corgi"), m_color("Black"), m_age(1) {}
         Dog(const Dog& d) { m_name = d.getName(); m_age = d.getAge(); }
         String getName() { return m_name; }
         int getAge() { return m_age; }
};

So when the copy constructor is called with a const dog object, how can this object access the getName() and getAge() functions? 因此,当使用const dog对象调用复制构造函数时,该对象如何访问getName()和getAge()函数?

A const member function is a member function that can't modify the class instance it's being called on. const成员函数是一个成员函数,它不能修改正在被调用的类实例。

So if you have a const object, you can only call the functions that are declared const , by appending const after the function prototype: 因此,如果您有const对象,则只能通过在函数原型后附加const来调用声明为const的函数:

void const_function(int i) const { /* function body */ }
                           ^^^^^

That's the only place the const can appear in, in order to make the function const . 为了使函数const ,这是const可以出现的唯一位置 Other places just modify the return type or the arguments. 其他地方只需修改返回类型或参数即可。


A copy constructor is a just a constructor that takes as an argument a const reference to an object of the same type. 复制构造函数只是将对相同类型对象的const引用作为参数的const The reference is const because the constructor does not modify the object passed as the argument, it just copies from it and constructs the new object with the copied data: 引用是const因为构造函数不会修改作为参数传递的对象,它只是从中复制并使用复制的数据构造新对象:

Foo(const Foo& copy_from_this_object) { /* copy member data from argument */ }

Also, the copy constructor doesn't actually copy the const ness from its argument, it just copies all the data from it. 另外,复制构造函数实际上并不从其参数复制const ,而只是从其复制所有数据。 Ie it doesn't matter whether the argument was const or not, it's just copied , not modified . 也就是说,参数是否为const无关紧要,它只是复制而不是修饰 The newly constructed may or may not be const . 新构造的可能const 也可能不是 It has nothing to do with the const ness of the copied-from object. 它有什么做的const复制的,从对象的湖。


Edit (after OP's edit): 编辑 (在OP编辑之后):

So when the copy constructor is called with a const dog object, how can this object access the getName() and getAge() functions? 因此,当使用const dog对象调用复制构造函数时,该对象如何访问getName()和getAge()函数?

It cannot . 不能

This is because the member functions are not properly marked const where they should have: 这是因为成员函数未正确标记为const ,它们应该在以下位置:

getName and getAge don't modify their class instance . getNamegetAge 不会修改其类实例 Therefore they should be const ! 因此,它们应该是const After making them const they can be called on the const object in the copy constructor, and the code will compile fine. 使它们成为const ,可以在复制构造const中的const对象上调用它们,并且代码可以正常编译。

Note: In general, you should always make getters const . 注意:通常,您应该始终使getters成为const That's because their task should be to only retrieve information about the object, not modify it. 那是因为他们的任务应该是仅检索有关对象的信息,而不是对其进行修改。

You just have to try compiling your code to see it doesn't work - from ideone.com here : 您只需要尝试编译代码以查看它是否无效-从ideone.com此处

prog.cpp: In copy constructor 'Dog::Dog(const Dog&)':
prog.cpp:13:46: error: passing 'const Dog' as 'this' argument of 'std::string Dog::getName()' discards qualifiers [-fpermissive]
       Dog(const Dog& d) { m_name = d.getName(); m_age = d.getAge(); }
                                              ^
prog.cpp:13:66: error: passing 'const Dog' as 'this' argument of 'int Dog::getAge()' discards qualifiers [-fpermissive]
       Dog(const Dog& d) { m_name = d.getName(); m_age = d.getAge(); }
                                                                  ^

You can fix it by making the "get" functions const : 您可以通过使“ get”函数为const来解决此问题:

string getName() const { return m_name; }
int getAge() const { return m_age; }

You can see that version compile successfully here 您可以在此处看到该版本已成功编译

It can't . 不能

Try it before asking. 询问之前先尝试一下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM