对具有相同参数签名

时间:2016-11-01 18:36:11

标签: c++ templates operator-overloading

我正在维基百科上阅读一篇关于表达模板的文章。

https://en.wikipedia.org/wiki/Expression_templates#Motivation_and_example

在本节中,有两种公共方法:

double &operator[](size_t i)      { return elems[i]; }
double operator[](size_t i) const { return elems[i]; }

第一个似乎返回一个非const引用,而第二个返回一个const double。这两种方法如何存在于同一个类中?

3 个答案:

答案 0 :(得分:5)

您无法单独通过返回类型区分,但您可以根据它们是否在对象的const个实例上运行来区分不同的成员函数。

使用链接中的代码的示例:

#include <vector>
#include <assert.h>

class Vec {
    std::vector<double> elems;

public:
    Vec(size_t n) : elems(n) {}

    double &operator[](size_t i) { return elems[i]; }
    double operator[](size_t i) const { return elems[i]; }
    size_t size()               const { return elems.size(); }
};

Vec operator+(Vec const &u, Vec const &v) {
    assert(u.size() == v.size());
    Vec sum(u.size());
    for(size_t i = 0; i < u.size(); i++) {
        sum[i] = u[i] + v[i];
    }
    return sum;
}

int main()
{
    Vec vec1{5};
    auto val1 = vec1[2]; // calls the first
    const Vec vec1r{5};
    auto val1c = vec1r[2]; // calls the second
    return 0;
}
  

为什么elems[i]可以为一个方法将引用返回给double,   elems[i]可以为另一个返回double吗?

这些是不同的功能:

double &operator[](size_t i);
double operator[](size_t i) const;

可能会返回不同的类型。

  

Elems是std::vector<double>elems[i]如何有时返回   引用double,有时会返回double

在第一种情况下不复制该值,仅返回引用。在第二种情况下复制返回值。

std::vector<double>::operator[]在第一种情况下返回引用,在第二种情况下返回const引用。但如前所述,在第二种情况下从const收到的std::vector引用被复制作为Vec函数的返回值。

答案 1 :(得分:3)

  

第一个似乎返回一个非const引用到双,

是的,double &是对double的非const引用。

  

而第二个返回const double。

不,它只是按值返回double

  

这两种方法如何存在于同一个类中?

const限定方法,而不是返回类型。你可以重载const限定。

this指针视为隐式参数 - 您可以根据它是否指向const对象来重载方法,就像任何其他参数一样。

例如,这些重载是合法的,但是因为它们在参数类型上重载,而不是返回类型。 (一旦你有一个允许的过载,你当然可以有不同的返回类型,这是不够的。)

int  deref(const int *p) { return *p; }
int& deref(int *p)       { return *p; }

const int i = 42;
int j = deref(&i); // ok, returns by value
// deref(&i) = 24; // not ok, assigns to temporary
deref(&j) = 24;    // ok again, this uses the second overload
assert(i == 42);
assert(j == 24);

完全相同的方法适用于方法,但使用不同的语法(this指针是隐式的,因此您不能将其作为带/不带const的参数直接写出来。

答案 2 :(得分:1)

成员函数声明末尾的const表示当类的对象为const时,它是可调用的。 (它不适用于返回类型。)

因此,如果v[i]不是v - 符合条件,则表达式const会调用第一个符号,如果v const符合printHangman,则表达式public class Hangman2 { public static void main(String[] args) { System.out.println("Welcome to HangMan Player 1, Please enter a word. Player 2, Please close your eyes: "); Scanner stdin = new Scanner(System.in); String secretWord = stdin.next(); for (int x = 1; x <= 100; x++) { System.out.println(" "); } System.out.println("Clearing Screen"); System.out.println("The current partial word is: "); String initialWord = createPartialWord(secretWord); System.out.println(""); System.out.println("The current hangman picture is: "); } public static String createPartialWord(String secretWord) { String newsecretWord = ""; int wordLength = secretWord.length(); while (wordLength > 0) { newsecretWord = newsecretWord + "-"; System.out.print("-"); wordLength--; } return newsecretWord; } public static String replaceChar(String word, char c, int i) { if(0 < i && i < word.length()) { return word.substring(0, i) + c + word.substring(i + 1); } return word; } public static String updatePartialWord(String partial, String secret, char c) { for (int i = 0; i <= secret.length(); i++) { if (secret.charAt(i) == c) { return replaceChar(partial, c , i); } } return partial; } public static void printHangman(int guessLeft) { String HEAD = " "; String BODY = " "; String LEGS = " "; String LEFTARM = " "; String RIGHTARM = " "; System.out.println("_____"); System.out.println("| |"); if (guessLeft < 6) { HEAD = "()"; } System.out.println("| " + HEAD); if (guessLeft < 5) { BODY = "||"; } if (guessLeft < 4) { LEFTARM = "\\"; } if (guessLeft < 3) { RIGHTARM = "/"; } System.out.println("| " + LEFTARM + BODY + RIGHTARM); if (guessLeft < 2) { LEGS = "/"; } if (guessLeft < 1) { LEGS += "\\"; } System.out.println("| " + LEGS); System.out.println("|_____\n\n\n\n"); } }