更改保留指向其字段的原始指针的对象地址
change address of object that keeps raw pointer to its field
我想重新分配一个名为CarJoker
的具有自引用的类
。重新分配"在这里意味着 = 更改对象的地址。
此技术对于使CarJoker
的每个实例都存在于可调整大小的连续数组(例如池(中是必要的。
我想使用std::move
,但它不能以我希望的方式移动CarJoker::wheels
。
(麦克维(
#include <vector>
#include <iostream>
#include <string>
struct Wheel{
void setBlade(){}
void setTwinkle(){}
};
struct CarJoker{
Wheel wa;
Wheel wb;
Wheel wc;
std::vector<Wheel*> wheels;
float hp=5;
CarJoker(){
wheels.push_back(&wa);
wheels.push_back(&wb);
wheels.push_back(&wc);
}
void wow(){
//v want to apply something to every "wheel"
for(auto wheel:wheels){
wheel->setBlade();
}
//v want to apply something to some certain "wheel"
wa.setTwinkle();
}
};
int main(){
CarJoker car1;
CarJoker car2=std::move(car1);
std::cout<<"want to 1 : "<<(car2.wheels[0]== &car2.wa)<<std::endl;
}
有了std::move
,car2.wheels[0]
指出&car1.wa
没有像我希望的那样&car2.wa
。
我知道原因,但这不是我的目标,我不知道一种优雅的方法来解决这个问题。
我糟糕的解决方法
这是一种不优雅的方式(MCVE(:-
struct CarJoker{
Wheel wa;
Wheel wb;
Wheel wc;
std::vector<Wheel*> wheels;
float hp=5;
CarJoker(){
reIni(); //: CHANGE (call a new function)
}
void reIni(){ //: CHANGE (create a new function)
wheels.clear();
wheels.push_back(&wa);
wheels.push_back(&wb);
wheels.push_back(&wc);
}
void wow(){
//v want to apply something to every "wheel"
for(auto wheel:wheels){
wheel->setBlade();
}
//v want to apply something to some certain "wheel"
wa.setTwinkle();
}
};
int main(){
CarJoker car1;
CarJoker car2=std::move(car1);
car2.reIni(); //: CHANGE (call a new function)
std::cout<<"want to 1 : "<<(car2.wheels[0]== &car2.wa)<<std::endl;
}
缺点:-
1。它很脏。
2.我必须为池中具有此类症状的每个类创建一个特殊名称函数(reIni()
(。 我的池也必须识别该功能(例如,使用模板或虚拟函数注册(。
我糟糕的解决方法 2
struct CarJoker{
Wheel wa;
Wheel wb;
Wheel wc;
std::vector<Wheel*> getWheels(){ //use this instead of "wheels"
std::vector<Wheel*> re;
re.push_back(&wa);
re.push_back(&wb);
re.push_back(&wc);
return re;
}
....
}
我会工作,但我觉得这样的解决方法很疯狂。
该限制增加了编码人员的陷阱。
如果wheels
碰巧需要缓存计算成本高昂的结果,那么现在经常调用getWheels()
会很昂贵。
您不需要reIni()
方法。您需要添加:
和移动构造函数,它们都以与默认构造函数相同的方式初始化
wheels
成员。
复制赋值运算符和移动指派运算符,它们不复制/移动
wheels
成员。
试试这个:
struct CarJoker{
Wheel wa;
Wheel wb;
Wheel wc;
std::vector<Wheel*> wheels;
float hp = 5;
CarJoker(){
wheels.push_back(&wa);
wheels.push_back(&wb);
wheels.push_back(&wc);
}
CarJoker(const CarJoker &src) :
CarJoker(),
wa(src.wa),
wb(src.wb),
wc(src.wc),
//wheels(src.wheels),
hp(src.hp){
}
CarJoker(CarJoker &&src) :
CarJoker(),
wa(std::move(src.wa)),
wb(std::move(src.wb)),
wc(std::move(src.wc)),
//wheels(std::move(src.wheels)),
hp(src.hp){
}
// copy assignment and move assignment can be
// handled with a single implementation that
// lets the compiler choose between the copy
// constructor and move constructor as needed...
CarJoker& operator=(CarJoker rhs){
wa = std::move(rhs.wa);
wb = std::move(rhs.wb);
wc = std::move(rhs.wc);
wheels = std::move(rhs.wheels);
hp = rhs.hp;
return *this;
}
...
};
话虽如此,您真的不应该一开始就使用自引用字段。单个std::array<Wheel, 3>
字段比 3 个Wheel
字段和一个std::vector<Wheel*>
字段更有意义,从而避免了整个问题。
struct CarJoker{
std::array<Wheel, 3> wheels;
float hp = 5;
CarJoker() = default;
CarJoker(const CarJoker&) = default;
CarJoker(CarJoker&&) = default;
CarJoker& operator=(const CarJoker&) = default;
CarJoker& operator=(CarJoker&&) = default;
Wheel& wa() { return wheels[0]; }
const Wheel& wa() const { return wheels[0]; }
Wheel& wb() { return wheels[1]; }
const Wheel& wb() const { return wheels[1]; }
Wheel& wc() { return wheels[2]; }
const Wheel& wc() const { return wheels[2]; }
void wow(){
//v want to apply something to every "wheel"
for(auto &wheel : wheels){
wheel.setBlade();
}
//v want to apply something to some certain "wheel"
wa().setTwinkle();
}
};
相关文章:
- 从堆栈分配的原始指针构造智能指针
- 将unique_ptr分配给原始指针
- 如何将唯一指针的 std::vector 转换为原始指针的 std::span?
- <Base> <Derived> 具有相同原始指针共享引用的 shared_ptr 和 shared_ptr 实例是否计数?
- C++原始指针和"delete"
- 为什么 C++ 地址中的矢量无法通过原始指针访问
- 如何正确实现具有原始指针的类的复制构造函数?
- 如何在将原始指针移动到基类构造函数之前从unique_ptr中提取原始指针
- 为包含原始指针的对象C++智能指针
- c++:复制、删除和运算符=在原始指针映射中
- C++模板,用于通过常量引用和原始指针传递向量
- C++为什么原始指针不会增加shared_ptr的引用计数?
- 从shared_ptr获取原始指针以将其传递给需要 raw 的函数
- 如何包装多级原始指针以赋予其容器语义
- 为什么我可以通过原始指针而不是shared_ptr来修改对象
- 将原始指针传递给接受unique_ptr作为参数的函数
- 为什么我们不允许将纯引用参数传递给 std::thread,但允许传递原始指针?
- 更改保留指向其字段的原始指针的对象地址
- 从原始指针(衰减的 C 样式数组)和大小生成范围::视图
- 如何在C++代码中灵活使用和替换标准::shared_ptr或标准::unique_ptr或原始指针?