2010-06-16 33 views
8

我刚刚遇到各种重载方法,如类型的参数传递,参数不同,返回类型等我只想知道,我可以超过以下两个版本的功能可以重载是可能的两个版本的函数,常量成员函数和函数没有const

 

//function which can modify member 
String& MyClass::doSomething(); 

//constant member function 
String& MyClass::doSomething() const; 

请让我知道背后的原因。

+0

你在用什么语言?如果您希望得到正确的关注,您应该用该语言标记问题。 – Oded 2010-06-16 19:50:03

+0

编辑,我使用的语言是C++ – 2010-06-16 19:55:33

+0

你不能在C++的返回类型上重载。 – Job 2010-06-16 20:00:36

回答

9

是的,你可以。

如果你有

MyClass m; 
m.doSomething(); 

非const版本将被调用。当你有

const MyClass m; 
m.doSomething(); 

const的版本将被调用。

2

是的,你可以做到这一点。 (@Job,这不是返回类型的重载,这是被调用类实例的'const-state'的重载)

如果实例是const,则会调用第二个变体,如果不是,第一个被称为。 实际使用是,如果方法被调用一个const例如,你可能还需要返回一个“常量字符串&”(例如,如果您返回到类的成员的引用),就像这样:

//function which can modify member 
String& MyClass::doSomething(); 

//constant member function 
const String& MyClass::doSomething() const; 
+0

我知道这个问题不是关于返回类型的重载问题,但他在他的问题中提到他认为这是可能的。 – Job 2010-06-16 20:11:19

1

这不仅是可能的,它作为一个常用的习惯用法。

例如,如果调用const版本的函数,则可以返回对只读版本结果的引用。但是,如果调用非const版本,则构造并返回接收器可能修改的副本。通过实施const版本,当我们知道不需要时,我们将从执行构建中被保存下来。

3

最简单的方法来理解这一点,是想你所呼叫的方法作为第0参数的对象:

如:想想

String& MyClass::doSomething(); 
MyClass mc; 
mc.doSomething(); 

的花哨,编译器支持的方式这样做的:

String& MyClass_doSomething(MyClass *this); 
MyClass mc; 
MyClass_doSomething(&mc); 

现在,超载基于常量性是只是参数类型超载一个特殊情况:

String& MyClass::doSomething(); 
String& MyClass::doSomething() const; 

可以通过思想为这样的事情:

String& MyClass_doSomething(MyClass *this); 
String& MyClass_doSomething(const MyClass *this); 

至于这个有用性,最简单的例子是各种std::容器beginend方法。如果vector/string /任何非常量,并且您拨打begin(),您将收回iterator,可用于修改原始容器的内容。显然,对于标记为const的容器,这是不允许的,因此,由于const/non const重载,在const向量上调用begin()返回的const_iterator可以用于读取向量的内容,但不能修改它。

例如

string nc = "Hello world"; 
for (string::iterator iString = nc.begin(); iString != nc.end(); ++iString) 
{ 
    cout << *iString;; // legal to read 
    *iString = toupper(*iString); // legal to write 

} 

const string c = "Hello world again"; 
for (string::const_iterator iString = c.begin(); iString != c.end(); ++iString) 
{ 
    cout << *iString;; // legal to read 
    // *iString = toupper(*iString); // Writing is illegal 
} 

至于通过返回类型重载,你不能用C++来完成。但是,你可以很体面地simulate it

2

这是如何使用迭代器。你有一个const迭代器和一个非const的迭代器。