为什么在我的函数类型后使用引用运算符 (&) 允许我修改它返回的值?
Why Does Using the Reference Operator(&) After my Function Type Allow me to Modify the Value it Returns?
我正在创建我自己版本的向量容器(以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
为什么使用引用运算符(&(。。。
它不是"引用运算符"。它根本不是操作员。您已将返回类型声明为引用类型。Lvalue引用更具体。
那么我就可以像在STL向量类中一样赋值了!我打感叹号是因为对我来说,这是一个惊喜。
如果您查看函数中标准库向量的返回类型,您会发现它还返回了一个引用。
我的想法是;操作员将返回给定索引处的值的地址
没有。它返回一个引用。(尽管,从技术上讲,编译器确实可以通过使用内存地址来实现间接(
并且[
myVec1.at(1) = 2;
]将myVec1的第二个元素的地址设置为2。
您的假设错误。指定给引用就是指定给引用的对象(不能将引用设置为引用另一个对象(。
我可以说"它正在返回对给定索引处数组值的引用吗?">
是。
国际上可用的符号数量有限,因此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
这两个运算符也可以在类中重载以执行其他操作(尽管应该谨慎使用(。
- 为什么在我的函数类型后使用引用运算符 (&) 允许我修改它返回的值?
- std::带有自定义缓冲区的 iostream 不允许我写入
- Visual Studio 2017 不允许我创建 C++ 专用模板
- 为什么在指向对象的迭代器上调用函数不允许我更改对象本身?
- 错误:从"int"到"int*"的转换无效[-允许].我在下面提供了我的代码,我
- C++ 我的开关格式中的循环不允许我显示菜单选项或接受输入?
- 为什么Visual Studio(2017;15.7.5)不允许我更改c ++关键字颜色
- HTTP POST 请求不允许我定义上下文类型
- 如何创建一个接口,允许我访问C++中的按钮(和其他ui)函数,该函数是使用python中的MFC实现的
- Bazel 允许我包含来自全局安装库的标头
- 为什么Visual Studio允许我在模板函数中使用私有成员(C++)?
- 新版本的 SDL 不允许我使用SDL_image
- 为什么C++不允许我在类中使用字符串作为数据成员?
- 为什么此代码不允许我接收整个数组?
- 为什么 C 允许我调用未声明的函数?
- 如何允许我的程序成功读取数字包含的文件
- 为什么我允许我为std :: vector设置end()
- 如果不允许我分配 rvalues 来引用为什么以下代码片段有效,这在内部如何工作?
- C++概念是否允许我的类在声明/定义中指定它满足某些概念?
- 如何允许我的应用程序C 请求ICMPV4?Windows 8.1