派生对象与基本对象位于同一位置
Derived Object at same Location as Base Object
我有一个问题,我在类"List"中有一个指向基类对象"元素"的指针。在某些情况下,我需要元素成为更专业的"过渡"类型。过渡派生自元素。但是当我创建一个从指针到 Element 对象的过渡对象时,指针现在与我的矩阵类 List 分离。
在我迄今为止的研究中,我读到,这是创建派生对象的方法。但这不是我想的...我希望派生对象与基类指针(指向 Element 类的指针,"last"(位于同一位置。我需要怎么做?
示例代码:
#include <iostream>
class Element{
public:
Element(){
member = 0;
}
virtual void set_member(int i){}
void print_member(){
std::cout << member << std::endl;
}
protected:
int member;
};
class Transition: public Element{
public:
void set_member(int i){
member = i;
}
};
class List{
public:
List(){
last = new Element;
}
Element* get_last(){
return last;
}
void print(){
last->print_member();
}
private:
Element* last;
};
int main(){
List list;
Element* last = list.get_last();
last = new Transition; // creates completely new entity.
// I wanted to make a derived object
// from Element at the same location
// as the Elememt object though
last->set_member(1);
last->print_member(); // returns newly assigned value
list.print(); // returns default value of Element type
// but I wanted itto return newly assigned value
}
Element* last = list.get_last();
last = new Transition;
现在局部变量last
与类List
中的成员变量last
无关,所以局部变量的行为不会影响成员变量last
。您可能需要一个 setor 方法来将其设置回来。如:
class List {
public:
void set_last(Element* e) {
last = e;
}
// ...
};
然后在main
:
int main() {
List list;
Element* last = new Transition; // creates completely new entity.
last->set_member(1);
list.set_last(last); // set it back to List
list.print();
}
[编辑]
BTW:你在类List
中使用了原始指针,你需要注意它的管理。例如,您应该在析构函数中delete
它,并在设置指向它的新指针之前,delete
旧指针,依此类推。一般来说,通过使用智能指针(如std::unique_ptr
(来采用RAII习语是一个更好的解决方案。
我希望派生对象与基类指针(指向 Element 类的指针,"last"(位于同一位置。我需要怎么做?
让我了解你想做什么。
你有:
Element* last = list.get_last();
此时,last
指向一个有效对象,该对象要么是Element
,要么是Element
的子类型。
现在,您要创建一个Transition
对象,并希望该对象的地址与last
指向的对象地址相同?
简短回答:不要这样做
长答案:
是的,您可以使用放置new
运算符执行类似操作。
但是,您必须先了解有关内存位置的所有信息,然后才能使用它。
您必须知道该位置有足够的内存来保存
Transition
对象。必须通过调用其析构函数来终止
存在在那里的对象的生命。程序的其他部分不会尝试使用以前的对象类型访问该内存位置。
不能在指针上调用
delete
。delete
必须在new
返回的同一指针类型上调用。否则,您将处于未定义的行为区域。如果使用
new []
运算符分配内存,则必须使用delete []
运算符解除分配内存。如果使用纯new
运算符分配内存,则必须使用纯delete
运算符解除分配内存。
可能还有更多我不记得的陷阱。
首先,正如其他人所说。我认为这需要重新考虑一下。
但鉴于您提出的问题,请注意:
Element* get_last(){
return last;
}
返回指向最后一个的指针(您新的东西(,但您不希望更改最后一个,而是希望将指针更改为最后一个。这可以像这样完成:
Element** get_last(){
return &last;
}
这将返回指向元素指针的指针。然后,您可以将该指针设置为新对象,但请注意,如果这样做,您只是泄漏了最初更新的元素的内存。所有新元素都必须删除(即使你按照松元瑶上面的评论去做......确保删除set_last和列表析构函数中的旧元素(。所以你最终会得到:
Element ** last = list.get_last();
delete(*last); // Removes the old entity from memory.
*last = new Transition; // creates completely new entity.
我想不出我会写这个的情况......在我看来,你确实需要一些重构。
我意识到我以一种过于复杂的方式处理我的问题。
我现在的解决方案是这样的:
#include <iostream>
class Element{
public:
Element(){
member = 0;
successor = 0;
}
virtual void set_member(int i){}
virtual void set_successor(int successor){}
void print(){
std::cout << member << std::endl;
std::cout << successor << std::endl;
}
protected:
int member;
int successor;
};
class Transition: public Element{
public:
void set_member(int i){
member = i;
}
void set_successor(int i){
successor = i;
}
};
class List{
public:
List(){
last = new Transition;
}
Element* get_last(){
return last;
}
void set_last(Element* new_last){
last = new_last;
}
void print(){
last->print();
}
private:
Element* last;
};
int main(){
List list;
(list.get_last())->set_member(6);
(list.get_last())->set_successor(8);
list.print();
}
- 如何仅使用对象名称打印特定于对象的成员
- 我有两个类需要在同一 cpp 文件中相互引用,但第一个类无法识别第二个类类型的对象
- 同一对象的"sizeof"的不同答案
- 链接时,不同静态库中的同一对象文件
- std::memmove在同一对象之间是否始终安全
- 对于BTreeMap和其他依赖于Ord的东西,是否有等效于C++比较器对象?
- 如何根据C++在同一内存位置重新初始化 C# 中的对象(还是自动完成)?
- C++两个对象,其中包含指向同一数组不同部分的指针
- 非静态成员引用必须相对于特定对象
- C++中同一基础对象的多个键
- 确保在编译期间仅同时使用来自同一工厂的对象
- 如果对象在同一层次结构中,-Wreturn-std-move clang 警告是否正确
- std::memory_order_relaxed 相对于同一原子变量的原子性
- 如何在C 中的另一个对象的同一数据成员中输入另一个字符串
- 如何在c++中的两个函数中传递对象的同一实例
- 派生对象与基本对象位于同一位置
- 依赖于同一值的多个static_assert
- 如何知道TCP连接是否存在于同一机器上的两个进程之间
- 如何使同一类的对象在同一函数中做不同的事情
- 使用此指针检查对象的同一实例