我有几个与C++中引用的使用有关的问题.
在下面显示的代码中,它是如何工作的,而不是在线上给出错误q = "world";?
#include <iostream>
using namespace std;
int main()
{
char *p = "Hello";
char* &q = p;
cout <<p <<' '<<q <<"\n";
q = "World"; //Why is there no error on this line
cout <<p <<' '<<q <<"\n";
}
Run Code Online (Sandbox Code Playgroud)
如何将参考q重新初始化为其他内容?
不是字符串文字,p = "Hello"常量或只读空间?所以如果我们这样做,
q = "World";
Run Code Online (Sandbox Code Playgroud)
不会p改变应该是常量的字符串吗?
我已经阅读了有关C++引用类型变量的内容,因为它们无法重新初始化或重新分配,因为它们作为常量指针"内部"存储.所以编译器会给出错误.
但实际上如何重新分配参考变量呢?
int i;
int &j = i;
int k;
j = k; //This should be fine, but how we reassign to something else …Run Code Online (Sandbox Code Playgroud)这是创建具有引用成员的赋值运算符的有效方法吗?
#include <new>
struct A
{
int &ref;
A(int &Ref) : ref(Ref) { }
A(const A &second) : ref(second.ref) { }
A &operator =(const A &second)
{
if(this == &second)
return *this;
this->~A();
new(this) A(second);
return *this;
}
}
Run Code Online (Sandbox Code Playgroud)
它似乎编译并运行良好,但是当c ++倾向于表现出最不期望的未定义行为时,以及所有说它不可能的人,我认为我错过了一些问题.我错过了什么吗?
只要我的上一个问题出现了新的问题,重载赋值运算符会导致有关递归的警告,我被合法地敦促将其作为新的发布.我在类Player中有一个引用类成员,我想实现该类的复制构造函数和赋值运算符(=).我必须提到的是,目的是函数vector.erase的精细工作,因为没有它,就我而言它无法正常工作.我使用vector:vector allPlayers; Player类的成员是:
class Player
{
private:
int ID;
int pMoney;
int doubleIndicator;
int squarePosition;
Bank& bank;
string pName;
Square* capturedSquare;
multimap<string, PropertySquare*> squaresColBought;
multimap<string, House*> housesColBuilt;
}
Run Code Online (Sandbox Code Playgroud)
如果我想实现赋值运算符,是否必须避免使用引用作为类成员?地图成员怎么样?我该如何最终实现赋值运算符?
我不知道的另一个最重要的问题是当我擦除持有Player的向量的迭代器时,指针类成员指向的对象会发生什么.有帮助吗?
这是在具有参考字段的类上放置 new的答案的后续。
调用std::vector<A>::data()上型A具有参考或常量字段,将指针返回到对象可通过原始向量通过放置新的,这将导致一个的const或参考场来改变原始对象将被替换,而仍然被另一指针管理,通过调用返回data()。
例如:
struct A {
const int i = 0;
};
int main() {
std::vector<A> vec = {{1}, {2}};
auto ptr = vec.data();
std::cout << ptr[1].i << std::endl; // 2
vec.pop_back();
vec.push_back({3}); // placement new, inside
std::cout << ptr[1].i << std::endl; // 3
}
Run Code Online (Sandbox Code Playgroud)
C++17 试图通过引入来解决这些问题,std::launder但后来同意虽然std::launder可以解决其他问题,但它并没有真正解决上述用例的问题,如NB US042 中所述。
一些问题 - 对于C++20 之前的C++ 版本:
由于NB US042 …
我正在探索在C++中实现真(部分)不可变数据结构的可能性.由于C++似乎没有区分变量和变量存储的对象,因此真正替换对象(没有赋值操作!)的唯一方法是使用placement new:
auto var = Immutable(state0);
// the following is illegal as it requires assignment to
// an immutable object
var = Immutable(state1);
// however, the following would work as it constructs a new object
// in place of the old one
new (&var) Immutable(state1);
Run Code Online (Sandbox Code Playgroud)
假设没有非平凡的析构函数可以运行,这在C++中是合法的还是我应该期望未定义的行为?如果它依赖于标准,那么我可以期待这个最小/最大标准版本能够工作吗?
因此,一旦std::pair初始化了至少一个引用变量,例如像这样:
int a = 53;
int b = 42;
std::pair<int, int&> foo(33, a);
Run Code Online (Sandbox Code Playgroud)
有没有办法改变引用变量的指向?
任务:
foo = std::make_pair(33, std::ref(b));
Run Code Online (Sandbox Code Playgroud)
和交换:
std::pair<int, int&> bar(33, b);
foo.swap(bar);
Run Code Online (Sandbox Code Playgroud)
似乎只是将新内容移动到a并留下foo指向它之前 ( a)位置的第二个成员,因此没有做我在这里试图实现的目标。我知道引用不能像这里回答的那样反弹
,但这不是我在这里想要做的。我想要做的是制作一对新的并将其内容分配给现有的,这在技术上不是一回事。
提前致谢!