繁体   English   中英

C ++构造函数 - 通过引用传递仅适用于const。 为什么?

[英]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;
}

现在,几个问题:

  1. 为什么没有const的代码无法通过引用传递? 在构造函数中始终通过引用传递是一种好习惯,如果是这样,那么我们必须使用const关键字?
  2. 因此,如果我在构造函数中传递值,则说: 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.

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