如何解决C ++前向声明+ ifndef也需要指针
数组:
#ifndef ARRAY_H
#define ARRAY_H
#include <bits/stdc++.h>
using namespace std;
namespace Maifee{
class Value;
class Array {
public:
Array();
vector<Value> _elements;
};
}
#endif // ARRAY_H
对象:
#ifndef OBJECT_H
#define OBJECT_H
#include <bits/stdc++.h>
#include "value.h"
using namespace std;
namespace Maifee{
class Value;
class Object{
public:
Object();
map<string,Value> _members;
};
}
#endif // OBJECT_H
值:
#ifndef VALUE_H
#define VALUE_H
#include <bits/stdc++.h>
#include "array.h"
#include "object.h"
using namespace std;
namespace Maifee{
class Array;
class Object;
class Value {
public:
Value();
Value(Object *__object);
Array *_array;
Object *_object;
};
}
#endif // VALUE_H
我正在努力学习C ++。凭借我很少的C ++知识,我正在尝试编写一些代码。我使用C ++的第一个原因是,指针要花很多时间。
在这里,我正在编写这些代码,其中需要进行前向声明,并且由于这个原因,即使在使用了前向声明和ifndef之后,我也需要使用指针,我真的不想要。
有人可以帮助我吗,如何删除循环依赖?
我需要回到C吗?
使用指针时,我遇到了许多问题,例如,我的地图中只有一对键值对,但是在下一行中,行大小变得非常大,无处不在。
main内部的代码:
Object object=Object();
cout << "pop obj tem len" << object._members.size() << endl; //gives 0 as expected
object._members = members;
cout << "pop obj tem len" << object._members.size() << endl; //gives the expected number
Value val=Value(&object);
cout << val._object->_members.size() << "size here" << endl; //gives a random number
具有Object参数的值的构造函数:
Value::Value(Object *__object)
{
Object object;
object._members.insert(__object->_members.begin(),__object->_members.end());
_object = &object;
}
解决方法
在这种情况下,您不能避免使用前向声明和指针。
class Object
有一个map<string,Value>
成员,而class Array
有一个vector<Value>
成员。这意味着Value
在编译Object
和Array
时必须是完全定义的完整类型,因为map
和vector
需要知道其元素类型的总大小。如果Value
具有非指针Array
和Object
成员,那么Object
和Array
将需要Value
是完整类型,但Value
将需要Object
和Array
为完整类型。赶上22!
因此,由于允许不完整类型的指针/引用,因此必须Value
成员使用前向声明和指针/引用才能使这种循环引用正常工作。
更新:在使用Value
参数的Object*
构造函数中,您正在将_object
成员设置为指向本地Object
实例超出范围并在构造函数退出时被销毁,从而使_object
晃来晃去。这就是为什么val._object->_members.size()
中后续的main()
表达式产生垃圾的原因(您很幸运代码没有完全崩溃)-val._object
指向无效的内存,因此其members
不是有效的map
对象,因此读取其size()
是未定义的行为。这可以追溯到我发表的原始评论:
您可能正在访问无效的指针。
要解决此问题,根据您的实际设计目标,Value
构造函数需要执行以下任一操作:
- 动态构建新的
Object
,稍后必须delete
进行构建。您还必须提供适当的副本构造函数和副本分配运算符:
Value::Value()
{
_object = NULL;
_array = NULL;
}
Value::Value(Object *__object)
{
_object = new Object;
_array = NULL;
if (__object)
_object._members = __object->_members;
}
Value::Value(const Value &__value)
{
_object = new Object;
_array = NULL;
if (__value._object)
_object._members = __value._object->_members;
}
Value::~Value()
{
delete _object;
}
Value& Value::operator=(const Value &__value)
{
if (&__value != this)
{
Value tmp(__value);
std::swap(_object,tmp._object);
std::swap(_array,tmp._array);
}
return *this;
}
- 只需存储给出的
Object*
指针:
Value::Value(Object *__object)
{
_object = __object;
_array = NULL;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。