直到那时我常常应对,这里我正在尝试使用vector构建我自己的容器类。我的工作需要它。我正在使用 codeblocks 10.05
class myclass
{
public :
vector<myclass> array;
char * classname;
...
问题是,如果我的类的数据在析构函数中没有删除,那么会很好地显示在屏幕上。我的函数show()如果我删除了classname,则会显示奇数字符。我认为它来自我的构建对象的方法和范围问题,当我将它们作为参数传递时。
myclass::~myclass()
{
//if(classname) delete [] classname;
}
这是在构造函数中初始化的方式:
myclass::myclass(long lvl = 0, const char name[] = "undefined")
:ID(++ ID_counter)
{
level = lvl;
int namelength = strlen(name);
classname = new char[namelength + 1];
strcpy(classname, name);
}
add_content(const myclass&amp; c)应该在这个&gt;数组中复制c.array的元素和“push_back”它们 我发现我们可以放置一个没有名字的对象作为参数: mycontainer.add_content(myclass(3,5)); 它有效,但我对其应有的范围持怀疑态度
> int main()
> {
> myclass mycontainer(0);
> mycontainer.add_content(myclass(3,5));
> ...
以下是完整代码:
#include <vector>
#include <iostream>
using namespace std;
class myclass
{
public :
vector<myclass> array;
static long ID_counter;
long ID;
long level;
char * classname;
myclass(int n, long lvl, const char name[]); //push_back n elements, lvl = 0, name = "undefined"
myclass(long lvl, const char name[]); //lvl = 0, name = "undefined"
myclass::~myclass();
void set_level(long lvl); //recursive function, go down the tree
void add(int n); //push_back n elements
void add(const myclass & c); //push_back and set back the levels
void add_content(const myclass & c); //push_back all the c.array[i] and set back the levels
void show();
template <typename T> myclass & operator[](const T it){ return array[it]; }
};
long myclass::ID_counter = 0;
myclass::myclass(long lvl = 0, const char name[] = "undefined")
:ID(++ ID_counter)
{
level = lvl;
int namelength = strlen(name);
classname = new char[namelength + 1];
strcpy(classname, name);
}
myclass::myclass(int n, long lvl, const char name[] = "undefined")
:ID(++ ID_counter)
{
level = lvl;
int namelength = strlen(name);
classname = new char[namelength + 1];
strcpy(classname, name);
for(int i = 0; i < n; i++) array.push_back( myclass(this->level + 1) );
}
myclass::~myclass()
{
//if(classname) delete [] classname; //there is the point !
}
void myclass::add(int n = 1)
{
for(int i = 0; i < n; i++) array.push_back( myclass(level + 1) );
}
void myclass::add(const myclass & c)
{
array.push_back(c);
array[array.size() - 1].set_level(level + 1);
}
void myclass::add_content(const myclass & c)
{
for(int i = 0; i < c.array.size(); i++)
{
array.push_back(c.array[i]);
array[array.size() - 1].set_level(level + 1);
}
}
void myclass::set_level(long lvl)
{
level = lvl;
for(int i = 0; i < array.size(); i++) array[i].set_level(level + 1);
}
void myclass::show()
{
cout << "ID : " << ID << "\tLvl : " << level << "\t Classname : " << classname << endl;
}
int main()
{
myclass mycontainer(0); //ground level
mycontainer.add_content(myclass(3,5)); //the 3 elements level 5 should be reset to 0+1
mycontainer.show();
for(int i = 0; i < mycontainer.array.size(); i++)
{
mycontainer[i].show();
for(int j= 0; j < mycontainer[i].array.size(); j++)
mycontainer[i][j].show();
}
cout << "\ncheckpoint\n";
system("PAUSE"); //press any key to crash!
return 0;
}
这里在析构函数中没有删除* classname ,程序就是这样:
ID : 1 Lvl : 0 Classname : undefined
ID : 3 Lvl : 1 Classname : undefined
ID : 4 Lvl : 1 Classname : undefined
ID : 5 Lvl : 1 Classname : undefined
checkpoint
Appuyez sur une touche pour continuer...
删除,一些不良字符出现崩溃:
ID : 1 Lvl : 0 Classname : undefined
ID : 3 Lvl : 1 Classname : ░(?
ID : 4 Lvl : 1 Classname : ░(?
ID : 5 Lvl : 1 Classname : ░(?
checkpoint
Appuyez sur une touche pour continuer...
Process returned -1073741819 (0xC0000005) execution time : 29.651 s
Press any key to continue.
我试图回顾一些关于论点和指针的原则,但这种语言过于经验,没有任何意义。谢谢你的帮助。
答案 0 :(得分:7)
您有一个原始指针,并没有定义复制构造函数或赋值运算符。这意味着您将获得自动生成的版本,这是您不想要的。回顾三法则。
解决方案#1:实现适当的复制构造函数和赋值运算符。
解决方案#2:将char * classname
更改为std::string classname
。现在,自动生成的复制构造函数和赋值运算符将起作用。附加好处:您无需使用new
,也无需使用delete
。
答案 1 :(得分:1)
您应该定义复制构造函数。
我的调试器在这里引发错误:
for(int i = 0; i < n; i++) array.push_back( myclass(this->level + 1) );
我们在这里看到,创建了myclass
的新对象,然后将其复制(克隆)到array
,然后将原始文件作为任何局部变量进行销毁。
因此,我们有两个具有相同指针的实例:一个被销毁,另一个在array
内,由默认复制构造函数创建,只复制原始内存。因此,array
内的实例无效,因为析构函数已在其上运行。
代码
以下附加构造函数将解决这种情况:
myclass::myclass(const myclass& other)
:ID(++ ID_counter)
{
level = other.level;
int namelength = strlen(other.classname);
classname = new char[namelength + 1];
strcpy(classname, other.classname);
}
(上面是所谓的“复制构造函数”;是的,当然你应该遵守“三规则”以避免所有潜在的错误)