我正在维基百科上阅读一篇关于表达模板的文章。
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。这两种方法如何存在于同一个类中?
答案 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");
}
}
。