[英]C++ Constructor — pass by reference only works with const. Why?
所以今天早些时候,我正在追赶好的旧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
但是,在构造函数Names(string const &name, string const &surname) : _name(name), _surname(surname) {}
添加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
为null或者是传递的值。 我知道在传递值时,正在制作变量的副本,并且正在对副本进行更改。 但是什么时候副本会被破坏或超出范围? 这有点令人困惑。 谢谢
必须将字符串文字转换为std::string
,这将是一个临时的,并且您不能通过非const引用传递临时 std::string
。
在@ 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;
}
住在Coliru's。
正如您从输出中看到的那样
[...]
===================
foobaring A&
foobared a
-------------------
A(int) ctor
foobaring const A&
A dtor
foobared 42
===================
[...]
在第二个foobar
调用中隐含了A
从该int参数中获得的临时A
,并且临时A
实例被传递给另一个实例,即foobar
的const版本,因此作为const A &
。
你还可以在第二个foobar
返回后,那个临时的A
被摧毁了。
1-“Mike”和“Man”在你对构造函数的调用中是临时的,非const引用不能绑定到临时对象。 按值传递内置类型更有效,所有其他对象通过const引用。
2-如果传递值_name
和_surname
将具有传递的值。 传递的参数副本对于函数是本地的,因此当构造函数超出范围时它们会被销毁。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.