为什么缺少此嵌套类的指针
Why is the pointer in this nested class missing?
简单问题:
B类具有ptr的PTR,该类别具有D类D类PTR
通过复制将B类分配给A类中的数组,期望在数组而不是原始实例中看到PTR点到新实例,但失败了。
我已经能够进行一些解决方法,但是我想知道为什么我的原始方法失败了。
更详细的解释如下,并且重现问题的代码也已发布
任何能够解释发生的事情的人都将受到赞赏。
有6个类:
类Castinfo//包含一个字符*
类技能//抽象课,包含Castinfo
班级移动:公共技能
类移动1:公共运动
类字符//包含一个运动*,在实践中将移动1*
类小队//包含一个字符
的数组具有以下关系:
角色* Castinfo中的角色*应指向拥有技能的角色是Castinfo的所有者
将技能分配给角色时,Castinfo中的字符*指向该字符
应该复制小队数组中的字符,因此将有2个实例,Castinfo中的字符*也应指向小队数组中的字符,而不是原始实例
期望结果是:
move1!= ch1.move1!= squad.ch [0] .move1(这已经满足)
ch1.move1-> cast_info.caster ==& ch1!= squad.ch [0] .move1-> casster_info.caster(这是问题)
输出有2例(尝试):
在小队的构造函数中:如果使用
characters_[i] = characters[i];
字符正确复制,但是技能在同一地址
move1: 00000270E6093500
ch1: 000000BC6DCFF378
ch1.move1: 00000270E6093E60
ch1.move1->cast_info.caster: 000000BC6DCFF378
squad.ch[0]: 000000BC6DCFF3E0
squad.ch[0].move1: 00000270E6093E60
squad.ch[0].move1->cast_info.caster: 000000BC6DCFF378
如果使用
characters_[i] = Character(characters[i]);
角色已正确复制,但是缺少技能(指向某些怪异的位置)
move1: 00000230FDCEF080
ch1: 00000058A11DF548
ch1.move1: 00000230FDCEF260
ch1.move1->cast_info.caster: 00000058A11DF548
squad.ch[0]: 00000058A11DF5B0
squad.ch[0].move1: 00000230FDCEF0E0
squad.ch[0].move1->cast_info.caster: 00000058A11DF378
在第一种情况下,我想这可能是因为我没有超载运算符=,因此仅复制地址。我试图超载它,但它引起了更多问题。(例如使用builder.build())
在第二种情况下,我希望它第一个调用复制构造函数,触发setMove1(),它调用setCaster()。如图所示,将MOVE1克隆到克隆中,但是我不明白为什么施法者未正确更新。(虽然是调用运算符=在约束后,地址应保持不变。)
以下代码应重现问题:
Motion.h
#pragma once
class Character;
struct CastInfo
{
Character* caster;
int coeff;
};
class Skill
{
public:
CastInfo cast_info;
Skill() {};
~Skill() {};
virtual void DoSomething() = 0;
};
class Movement : public Skill
{
public:
Movement();
~Movement();
virtual void DoSomething() { ; }
virtual Movement* Clone() const { return new Movement(*this); }
};
class Move1 : public Movement
{
public:
Move1() { cast_info.coeff = 123; }
void DoSomething() { ; }
virtual Move1* Clone() const { return new Move1(*this); }
};
class Move2 : public Movement
{
public:
void DoSomething() { ; }
};
Motion.cpp:
#include "motion.h"
Movement::Movement() { }
Movement::~Movement() { }
test.h:
#pragma once
#include <string>
#include <vector>
#include "motion.h"
#define SQUAD_SIZE 6
extern Movement* null_movement;
class Character
{
public:
class Builder;
Character();
~Character();
Character(const Character& character);
Character& SetMove1(Movement* skill);
public:
int id_;
Movement* move1_ = null_movement;
Movement* move2_ = null_movement;
Character(int id) : id_(id) { ; }
void SetCaster();
};
class Character::Builder : public Character
{
public:
Builder& SetId(int i) { id_ = i; return *this; }
Character Build() { return Character(id_); }
};
class Squad
{
public:
class Builder;
Squad() { }
Squad(const Squad& squad);
~Squad() { }
public:
Character characters_[SQUAD_SIZE];
Squad(Character* characters);
};
class Squad::Builder :public Squad
{
public:
Builder& SetCharacter(const Character& character, const int position) { characters_[position] = character; return *this; }
Squad Build() { return Squad(characters_); }
};
test.cpp
#include <iostream>
#include "test.h"
Movement* null_movement = new Move2();
Character::Character() : id_(0) { }
Character::~Character() {}
Character::Character(const Character& character) {
id_ = character.id_;
SetMove1(character.move1_);
}
Character& Character::SetMove1(Movement* move1) {
if (!move1) return *this;
move1_ = move1->Clone();
SetCaster();
return *this;
}
void Character::SetCaster() {
if (move1_ != NULL) move1_->cast_info.caster = this;
}
Squad::Squad(const Squad& squad) {
*this = squad;
}
Squad::Squad(Character* characters) {
for (int i = 0; i < SQUAD_SIZE; i++) {
//characters_[i] = characters[i]; //character copied, skill same address
characters_[i] = Character(characters[i]); //character copied, skill missing
}
}
main.cpp
#include <iostream>
#include "test.h"
#include "motion.h"
int main() {
Move1* move1 = new Move1();
std::cout << "move1: " << move1 << std::endl;
Character ch1 = Character::Builder().SetId(1).Build();
Character ch2 = Character::Builder().SetId(2).Build();
ch1.SetMove1(move1);
std::cout << "ch1: " << &ch1 << std::endl;
std::cout << "ch1.move1: " << (ch1.move1_) << std::endl;
std::cout << "ch1.move1->cast_info.caster: " << (ch1.move1_->cast_info.caster) << std::endl;
Squad squad = Squad::Builder().SetCharacter(ch1, 0).SetCharacter(ch2, 1).Build();
std::cout << "squad.ch[0]: " << &(squad.characters_[0]) << std::endl;
std::cout << "squad.ch[0].move1: " << (squad.characters_[0].move1_) << std::endl;
std::cout << "squad.ch[0].move1->cast_info.caster: " << (squad.characters_[0].move1_->cast_info.caster) << std::endl;
system("PAUSE");
return 0;
}
如前所述,我有一个解决方法可以实现我的目标:
通过创建另一种方法,该方法通过小队中的数组迭代,并调用每个字符的setCaster()方法。
void Squad::SetCaster() {
for (int i = 0; i < SQUAD_SIZE; i++) {
characters_[i].SetCaster();
}
}
但我认为这很脏
我想我发现了问题,如下所示:
问题在
中Squad::Squad(Character* characters) {
for (int i = 0; i < SQUAD_SIZE; i++) {
//characters_[i] = characters[i]; //character copied, skill same address
characters_[i] = Character(characters[i]); //character copied, skill missing
}
}
如所提到的,使用注释的行只是复制该值,这是不正确的。
什么
characters_[i] = Character(characters[i]); //character copied, skill missing
确实如下:
创建一个字符,通过调用字符的约束,该对象在地址A. setMove1()被调用,setCaster()被调用。cast_info中的指针正确指向一个。
将对象分配给字符_ [i],其地址在地址B处,因为在创建小队时分配了字符的地址。因为我没有超载字符:: operator =,指针仍指向地址
构造函数完成,小队返回。
这是原因
std::cout << "squad.ch[0].move1->cast_info.caster: " << (squad.characters_[0].move1_->cast_info.caster) << std::endl;
显示了第三个地址(地址a),该地址既不是&amp;(artem [0])(地址b)和&amp; ch1(原始字符的地址)
解决方案要么是超载运算符=或将我的"解决方法"放在for循环之后的构造函数中。
。如果有任何问题,请纠正我,或者有更好的解决方案。
- 嵌套类、继承和C++中的共享指针
- 如何从另一个嵌套类中调用某个封闭类的嵌套类的函数指针成员的值?
- 如何将值添加到嵌套结构中,该结构在C++中有两个指针
- 释放指向保留嵌套变量内存地址的结构的指针
- 带有指针的嵌套 foreach 循环?
- 包含指针成员的嵌套结构
- 通过嵌套的lambda中的值捕获指针导致Segfault
- 如何从嵌套类中访问指针
- 设计具有两个指向嵌套对象的指针的迭代器
- 通过指向成员的指针对嵌套访问进行编译时评估期间出现 GCC 错误
- 嵌套的 QVector 指针内存处理
- 为什么缺少此嵌套类的指针
- 嵌套类指针的特殊行为
- 嵌套智能指针运算符>
- 指向嵌套类中的成员函数的 C++ 指针
- 嵌套指针类型在iterator_traits有什么用?
- 访问模板参数T的嵌套类型,即使T是指针
- 正在为嵌套结构指针分配内存
- 在与 OpenMP 并行的嵌套 for 循环中写入共享数组(通过指针)如何产生错误的结果
- 嵌套绑定到成员,需要一个指针,得到了一个引用.做什么