可以使用两种版本的函数重载:常量成员函数和不带 const 的函数

发布于 2024-09-06 02:34:25 字数 243 浏览 8 评论 0原文

我刚刚遇到了各种重载方法,例如传递的参数类型、不同数量的参数、返回类型等。我只是想知道我可以使用以下两个版本重载函数吗?

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

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

请让我知道其背后的原因。

I just came across various overloading methods like type of parameter passed, varying number of parameters, return type etc. I just want to know that can I overload a function with following two version


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

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

Please let me know the reason behind it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

风苍溪 2024-09-13 02:34:25

是的,你可以。

如果你有

MyClass m;
m.doSomething();

非常量版本将会被调用。当你有

const MyClass m;
m.doSomething();

const 版本时将会被调用。

Yes you can.

If you have

MyClass m;
m.doSomething();

The non-const version will be called. When you have

const MyClass m;
m.doSomething();

The const version will be called.

纵山崖 2024-09-13 02:34:25

理解这一点的简单方法是将调用该方法的对象视为第 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);

至于它的用处,最简单的例子是各种 上的 beginend 方法std:: 容器。如果向量/字符串/无论什么都不是const,并且您调用begin(),您将得到一个迭代器< /code> 可用于修改原始容器的内容。显然,对于标记为 const 的容器不允许这样做,因此,由于 const/非 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++中是做不到的。但是,您可以相当不错地模拟它

The easy way to understand this, is to think of the object you are calling the method on as the 0th parameter:

e.g.: Think of

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

as a fancy, compiler supported way of doing this:

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

Now, overloading based on constness is just a special case of overloading by parameter types:

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

can by thought of as something like this:

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

As to the usefullness of this, the easiest examples are the begin and end methods on various std:: containers. If the vector/string/whatever is non const, and you call begin(), you'll get back an iterator that can be used to modify the contents of the original container. Clearly, this shouldn't be allowed for containers marked const, so, thanks to the const/non const overloading, calling begin() on a const vector return a const_iterator that can be used to read the contents of the vector, but not modify it.

e.g.

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
}

As to overloading by return type, you can't do it in C++. However, you can simulate it fairly decently.

旧街凉风 2024-09-13 02:34:25

是的,你可以这样做。
(@Job,这不是返回类型上的重载,这是被调用类实例的“const-state”上的重载)

如果实例是const,则将调用第二个变体,如果不是,则第一个变体是叫。
实际用途是,如果在 const 实例上调用该方法,您可能还想返回“const String&” (例如,如果您返回对该类成员的引用),如下所示:

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

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

Yes, you can do this.
(@Job, this is not overload on return type, this is overload on 'const-state' of the called class instance)

If the instance is const, the second variant will be called, if it isn't, the first one is called.
The practical use is that if the method is called on a const instance, you probably also want to return a "const String&" (e.g. if you return a reference to a member of the class), like this:

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

//constant member function
const String& MyClass::doSomething() const;
∞梦里开花 2024-09-13 02:34:25

这就是迭代器的使用方式。您有一个 const 迭代器和一个非常量迭代器。

This is how iterator is used. You have a const iterator as well as a non-const one.

韶华倾负 2024-09-13 02:34:25

这不仅是可能的,而且是一种常用的习语。

例如,如果调用函数的 const 版本,则可以返回对结果的只读版本的引用。但如果调用非 const 版本,则会构造并返回接收者可以修改的副本。通过实现 const 版本,当我们知道不需要它时,我们就可以避免执行构造。

Not only is this possible, it as a commonly used idiom.

For example, if the const version of a function is called, a reference to a read-only version of a result can be returned. But if the non-const version is called, a copy is constructed and returned that the receiver may modify. By implementing a const version, we are saved from performing the construction when we know it isn't going to be needed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文