我正在创建自己的矢量容器版本(以STL矢量容器为后缀),并且遇到了一个有趣的问题。我希望能够使用.at()函数将值分配给我的向量,例如:
vector<int> myVec1 = {1, 1, 3, 4};
myVec1.at(1) = 2; //assigning a value using .at()
所以我做了一些实验,发现如果使.at()函数像这样:
template <typename Type>
Type& My_vector<Type>::at(int const index) { //notice the ampersand(&)
return *(array + index);
}
然后我就可以像在STL向量类中那样分配值!我标上了感叹号,因为对我来说,这是一个惊喜。我的想法是,&运算符的这种使用将返回给定索引处的值的地址,并且执行以下操作:
My_vector<int> myVec1 = {1, 1, 3, 4};
myVec1.at(1) = 2;
将myVec1的第二个元素的地址设置为2。但是,情况并非如此,而是在其中更改了值。这对我很有用,因为我的目标是能够使用.at()赋值,但是我的问题是,当我说此函数此时应返回值的地址时,我的想法有什么缺陷? ?我的函数定义中的&运算符在这里实际上如何工作?我可以说“它正在返回对给定索引处的数组值的引用吗?”这似乎正在发生,但是,我认为我很了解&和*运算符在大多数情况下的工作方式。这是一个功能齐全的示例:
My_vector.h
#ifndef My_vector_h
#define My_vector_h
#include <cstring>
#include <type_traits>
#include <initializer_list>
template <typename Type>
class My_vector {
private:
Type* array;
int vector_size;
public:
//Copy Constructor
My_vector(std::initializer_list<Type> list) {
array = new Type[list.size() + 10];
vector_size = list.size();
memcpy(array, list.begin(), sizeof(Type) * list.size());
}
//Destructor
~My_vector() {delete [] array; array = nullptr;}
//Accessor .at()
int size() {return vector_size;}
Type& at(int const);
};
template <typename Type>
Type& My_vector<Type>::at(int const index) {
return *(array + index);
}
#endif /* My_vector_h */
main.cpp
#include <iostream>
#include "My_vector.h"
int main() {
My_vector<int> sampleVec = {1, 1, 3, 4};
for (int i = 0; i < sampleVec.size(); i++) {
std::cout << sampleVec.at(i) << " ";
}
std::cout << std::endl;
sampleVec.at(1) = 2;
for (int i = 0; i < sampleVec.size(); i++) {
std::cout << sampleVec.at(i) << " ";
}
std::cout << std::endl;
return 0;
}
输出:
1 1 3 4
1 2 3 4
答案 0 :(得分:2)
为什么使用引用运算符(&)...
它不是“引用运算符”。它根本不是运算符。您已将返回类型声明为引用类型。左值引用更具体。
然后我就可以像在STL向量类中那样分配值!我加上了感叹号,因为对我来说,这是一个惊喜。
如果您查看函数中标准库向量的返回类型,您会发现它还返回了引用。
我的想法是,&运算符的这种使用将返回给定索引处的值的地址
不是。它返回一个参考。 (尽管从技术上讲,编译器确实可以通过使用内存地址来实现间接寻址)
并且[[
myVec1.at(1) = 2;
]会将myVec1的第二个元素的地址设置为2。
您错误地假设。分配给引用是对引用对象的分配(不可能将引用设置为引用另一个对象)。
我可以说“它正在返回给定索引处的数组值吗?”
是的
答案 1 :(得分:1)
由于国际上可用的符号数量有限,因此c ++必须在不同的地方重用一些符号。
在与号的情况下,使用三个位置。
&运算符(的地址),用于表达式中以检索变量的地址,是星号或取消引用运算符的逆。例如:
int i = 1;
int* pi = &i; // store the address of i in pi
int j = *pi; // dereference the pi pointer and store the value in j
一个引用类型,在类型声明中使用它来声明一个像指针一样起作用的类型,但不需要解引用并且不能为null。例如:
int i = 1;
int & ri = i; // take a reference to i in variable ri
int j = ri; // store the value of the referenced variable in j
按位和运算符,它对两个数字进行二进制和运算。例如:
int i = 3;
int j = 2;
int k = i & j; // set k to 3 AND 2
这两个运算符也可以在类中重载以执行其他操作(尽管应谨慎使用)。