今天早些时候,我正在追赶好的旧C ++,当我编写代码时,它无法正常工作。像一些程序员一样,我开始讨厌,并最终发现添加键盘const
解决了这个问题。但是,我不喜欢黑客攻击很多,并希望在添加const
后找出代码工作正常的原因。
这是我的代码之前将const
添加到构造函数中:
#include <iostream>
#include <string>
using namespace std;
class Names {
private:
string _name;
string _surname;
public:
Names(string &name, string &surname) : _name(name), _surname(surname) {}
string getName() const {return _name;}
string getSurname() const {return _surname;}
};
int main(){
Names names("Mike", "Man");
cout << names.getName() << endl;
cout << names.getSurname() << endl;
}
我收到了这些错误:
names.cc:19:27: error: no matching function for call to ‘Names::Names(const char [5], const char [4])’
Names names("Mike", "Man");
^
names.cc:19:27: note: candidates are:
names.cc:11:2: note: Names::Names(std::string&, std::string&)
Names(string &name, string &surname) : _name(name), _surname(surname) {}
^
names.cc:11:2: note: no known conversion for argument 1 from ‘const char [5]’ to ‘std::string& {aka std::basic_string<char>&}’
names.cc:5:7: note: Names::Names(const Names&)
class Names {
^
names.cc:5:7: note: candidate expects 1 argument, 2 provided
<builtin>: recipe for target 'names' failed
make: *** [names] Error 1
但是,在构造函数const
中添加Names(string const &name, string const &surname) : _name(name), _surname(surname) {}
关键字后,它似乎正在运行。
这是我的工作代码:
#include <iostream>
#include <string>
using namespace std;
class Names {
private:
string _name;
string _surname;
public:
Names(string const &name, string const &surname) : _name(name), _surname(surname) {}
string getName() const {return _name;}
string getSurname() const {return _surname;}
};
int main(){
Names names("Mike", "Man");
cout << names.getName() << endl;
cout << names.getSurname() << endl;
}
现在,有几个问题:
const
传递代码,为什么代码无效
参考?总是通过引用传递给你的好习惯
构造函数,如果是这样,那就意味着我们必须使用const
关键词? Names(string name, string surname) : _name(name), _surname(surname) {}
这是否意味着_name
和_surname
为空或是他们
传递的价值。我知道传递值,变量的副本
正在制作并正在对副本进行更改。但是什么时候
副本会被毁坏还是超出范围?这有点令人困惑。由于
答案 0 :(得分:13)
string literal必须转换为std::string
,这是一个临时的,而你cannot pass a temporary by non-const reference。
答案 1 :(得分:2)
向@ CoryKramer的解释添加内容非常困难
必须将字符串文字转换为std :: string 一个临时的,你不能通过非const引用传递一个临时的。
这不仅仅是改写它。
无论如何,这是你(@ CodeMan)可以使用
的一些检测代码#include <iostream>
std::ostream& logger = std::clog;
struct A {
A() = delete;
A(int ii) : i(ii) {logger << "A(int) ctor\n";}
A(const A& a) : i(a.i) {logger << "A copy ctor\n";}
A& operator= (const A& a) { i = a.i; logger << "A copy assigment\n"; return *this;};
// nothing to steal here
A(A&& a) : i(a.i) {logger << "A move ctor\n";}
A& operator= (A&& a) {i = a.i; logger << "A move assigment\n"; return *this;};
~A() {logger << "A dtor\n";}
int i;
};
void foobar(const A& a) {
logger << "foobaring const A&\n";
}
void foobar(A& a) {
logger << "foobaring A&\n";
}
int main(){
int i(42);
A a(i);
logger << "ctored a\n===================\n";
foobar(a);
logger << "foobared a\n-------------------\n";
foobar(i);
logger << "foobared " << i << "\n===================" << std::endl;
}
live在Coliru's。
从输出中可以看出
[...]
===================
foobaring A&
foobared a
-------------------
A(int) ctor
foobaring const A&
A dtor
foobared 42
===================
[...]
在第二个foobar
调用中隐含地从该int参数中获取临时A
,并将该临时A
实例传递给另一个,即{{1的const版本因此,foobar
。
而且你也可以在第二次const A &
返回之后,暂时foobar
被删除。
答案 2 :(得分:0)
1-“Mike”和“Man”在你对构造函数的调用中是临时的,非const引用不能绑定到temporaries。 按值传递内置类型更有效,所有其他对象通过 const 引用。
2-如果您通过值_name
传递,_surname
将传递值。传递的参数副本对于函数是本地的,因此当构造函数超出范围时它们会被销毁。