我们所说的C++行是什么意思?有没有其他的方法来写它们呢?
const int& a() const;
int getA() const;
谢谢。
发布于 2011-03-31 07:26:19
这两个签名是承诺不更改对象本身的类中的成员函数的两个可能签名。在第一种情况下,它将返回一个对整数(可能是成员属性)的常量引用,引用为const
意味着调用者将无法使用它来更改内部属性。第二种情况,它通过值返回一个整数。
在语义上有一些细微的差异,但在大多数情况下,它们并不重要,可以将它们视为获取值的两个函数。对于它将会有所不同的情况,请参阅以下内容:
class test {
public:
test() : m_value() {
std::cout << &m_value << std::endl; // print where the attribute is
}
int const & getValue() const {
return m_value;
}
int copyValue() const {
return m_value;
}
void setValue( int value ) {
m_value = value;
}
private:
int m_value;
};
int main() {
test t; // will printout an address [1]
int v1 = t.getValue(); // caller copies the value
int v2 = t.copyValue(); // caller copies the value (itself a copy in hte calle)
int const &r = t.getValue(); // reference to t.m_value
int const &c = t.copyValue();// reference to *copy* [2]
std::cout << v1 << v2 << r << c
<< std::cout; // 0000
std::cout << &v1 << &v2 // 4 pointers, the third is [1] a r *is* t.m_value
<< &r << &c << std::cout; // the rest should be different
t.setValue( 5 );
std::cout << v1 << v2 << r // 0050, v1 and v2 where copies, r *is* t.m_value
<< c << std::cout;
}
标记为2的代码行使用了语言的一个奇怪特性,通过该特性,如果您获得一个对r值(临时)的常量引用,编译器将把该临时引用绑定到该引用,并使其保持活动状态,直到该引用超出范围为止(基本上它将r值临时变量转换为一个隐藏变量,并将该引用绑定到该变量)。
我添加了这一行是显式的,因为行为上的差异并不是由于接收端main
制作了一个维护引用的副本,而是(准确地说)是由访问者的签名造成的。
发布于 2011-03-31 08:16:09
这两种方法都是实现相同目标的等价方法:
const int& a() const;
int getA() const;
您正在返回一个值。方法头部右侧的常量是一个注释,函数getA()和a()不会修改将执行它们的对象(隐藏的this参数)。这在编译时很重要,因为这意味着在编译时将考虑额外的验证。在运行时,上面的函数和这些函数没有区别:
const int& a();
int getA();
然而,扩展编译器的验证功能的巨大好处(当您不期望它发生时,不会有任何改变)显然值得额外的const。
第二部分要担心的是这两个函数的返回类型,这代表了它们之间的主要区别,也可能是这个问题的动机。让我们将主题更改为不同的函数:
std::string getName() const;
{ return name; }
在这里,返回值可能是来自类的name属性。返回是通过值进行的,这意味着从该方法返回时将创建属性的副本。当字符串很大,并且您要在应用程序中按值移动大量字符串时,这可能是一个问题。然后,它恰好出现了按引用返回的机制,该机制承诺不复制:
std::string &getName() const
{ return name; }
这实际上非常有趣:我们返回一个引用,而不是对象的副本。引用类似于指针,因此您只需复制一个指针( 32位系统中为4个字节),而不是整个对象。这是很有希望的。但是,它甚至不会编译。编译器会抱怨你返回了一个引用,而你承诺的方法是const,因此,它将执行的对象不应该被修改。此代码将允许发生非法操作:
Person p( "Baltasar" );
p.getName() = "José";
cout << p.getName() << endl;
这就是为什么返回类型的const作为一个新的有吸引力的选项出现,它将解决这个问题。常量引用不允许修改它所指向的对象,使用:
const std::string &getName() const
{ return name; }
它现在可以编译了,而之前的恶意代码不能。现在让我们回到我们的问题上:
const int &getA() const;
int a() const;
第二个是按值返回,这意味着将在返回时复制int (4字节)。第一个表示将返回对int (4字节)的常量引用。可以看出,在这种情况下,使用按引用返回而不是按值返回对性能没有任何好处。
根据经验,按常量引用返回总是安全的,它永远不会比按值返回更昂贵。
发布于 2011-03-31 07:27:08
const int& a() const;
a()
返回对int
的常量引用。末尾的const
修饰符表示它不能更改在其上调用的对象的状态。
int getA() const;
除了返回类型是int
之外,与上面的描述相同,如果收集了返回变量的副本,则该类型涉及到该变量的副本。
说不能改变对象的状态是什么意思?
class foo
{
int m_Var ;
public:
foo(int arg1) : m_Var(arg1){}
void mutableMethod()
{
m_Var = 20 ; // "this" has the variable m_Var and
// by assigning it a value changes the state of
// m_Var. Changing the state of it's member variable
// is meant changing the state of object.
}
void nonMutableMethod() const
{
m_Var = 20 ; // This assignment is not allowed because of const
// modifier. The method is not allowed to change the
// the state of object on which it is called ( this )
}
};
此外,常量方法不能通过非常数引用返回成员变量。
https://stackoverflow.com/questions/5496491
复制相似问题