C++ 当 derived 和 base class 具有不同类型的参数时,我在继承方面遇到了一些严重的问题,如下所示:
C++ I have some seryous issues with inheritance when derived and base class have different types of parameters, like shown below:
我是 c++ 的新手,最近发现了 classes;
我学习了构造函数、重载运算符、三原则,现在我尝试学习继承。
我创建了 4 classes: 2 parents, 2 childs, 但我在 class parent1
这是class parent1:
class parent1{
protected:
float slr;
int age;
char *name;
void set_new_name(char ch[10001]);
public:
parent1()
{
slr=0.0;
age=0;
name=NULL;
}
parent1(char ch[10001], float sl, int ag)
{
slr=sl;
age=ag;
set_new_name(ch);
}
parent1(const parent1 &p1)
{
char temp[10001];
strcpy(temp,p1.name);
if(name != NULL)
delete[] name;
set_new_name(temp);
slr=p1.slr;
age=p1.age;
}
parent1 &operator=(const parent1 &p1)
{
/// same lines as in copy constructor above
return *this;
}
char* get_name() const;
void print1();
~parent1()
{
delete[] name;
}
};
这是他的childclass,child1:
class child1 : public parent1{
protected:
int id;
void set_id(int j);
public:
child1(): parent1()
{
set_id(0);
}
child1(char ch[10001],float sl, int ag, int j): parent1(ch,sl,ag)
{
set_id(j);
}
child1(const child1 &p2): parent1(p2)
{
set_id(p2.get_id());
}
child1 &operator=(const child1 &p2)
{
set_id(p2.get_id());
parent1::operator=(p2);
}
int get_id() const;
void print2();
};
有class parent 2:
class parent2{
protected:
char *name1;
char *name2;
void set_new_name1(char ch1[10001]);
void set_new_name2(char ch2[14]);
public:
parent2()
{
name1=NULL;
name2=NULL;
}
parent2(char ch1[10001], char ch2[14])
{
set_new_name1(ch1);
set_new_name2(ch2);
}
parent2(const parent2 &p3)
{
char temp2[10001];
strcpy(temp2,p3.name1);
if(name1 !=NULL)
delete[] name1;
set_new_name1(temp2);
/// .. . same lines as above, this time for name2 and p3.name2
}
parent2 &operator=(const parent2 &p3)
{
/// .. same lines as in copy constructor above
return *this;
}
char* get_name1() const;
char* get_name2() const;
void print3();
~parent2()
{
delete[] name1;
delete[] name2;
}
};
还有他的child,child2:
class child2: public parent2{
protected:
char *job;
void set_new_job(char ch3[15]);
public:
child2(): parent2()
{
job=NULL;
}
child2(char ch1[10001], char ch2[10001],char ch3[11]): parent2(ch1,ch2)
{
set_new_job(ch3);
}
child2(const child2 &p4): parent2(p4)
{
char temp6[11];
strcpy(temp6, p4.job);
if(job != NULL)
delete[] job;
set_new_job(temp6);
}
child2 &operator=(const child2 &p4)
{
/// same lines as in copy constructor
parent2::operator=(p4);
}
char* get_job() const;
void print4();
~child2()
{
delete[] job;
}
};
如你所见,class parent1 有 3 种类型的参数(一种浮点型、一种整型和一种字符*)。
Nonte: set_ functions works ok, get_functions just return class parametes (also works ok), print functions just print classes参数(例如:cout << name1;也可以正常工作)
问题是当我在 main 中创建 objects 时,这段代码拒绝工作。
一开始我以为是 operator= 被重载了很多次,结果是 parent1 的 float 参数
主要有:
char ch[10001]="my name", ch1[10001]="my name 1", ch2[14]="my name 2", ch3[11]="some code";
int ag=10;
float sl=10.1;
parent1 o1;
o1=parent1(ch,sl,ag);
o1.print1();
parent1 o2(o1);
o2.print1();
child1 o3;
o3=child1(ch,sl,ag,3);
o3.print2();
child1 o4;
o4=child1(ch,sl,ag,6);
o4.print2();
o4=o3;
o4.print2();
parent2 o5;
o5=parent2(ch1,ch2);
o5.print3();
child2 o6(ch1,ch2,ch3);
o6.print4();
似乎唯一 运行 是:
正在从 parent1 中删除浮点参数;
删除最后一个class; (真不知道为什么最后的class会影响程序)
像这样创建最后一个 object:child2 o6(ch1,ch2,ch3); ,这令人沮丧,因为它应该像其他人一样工作;
我知道我剪的代码很长,但是请,帮助我了解我需要什么解决这个愚蠢的错误!
我发现代码中至少有 3 个问题会导致 crash/undefined 行为。
第一个:
parent1(const parent1 &p1)
{
char temp[10001];
strcpy(temp,p1.name);
if(name != NULL) // name isn't initialized yet,
delete[] name; // these 2 lines shouldn't be here
set_new_name(temp);
slr=p1.slr;
age=p1.age;
}
其次:(这些是启用警告时编译器报告的)
child1 &operator=(const child1 &p2)
{
set_id(p2.get_id());
parent1::operator=(p2);
return *this; // this line is missing
}
第三名:
child2 &operator=(const child2 &p4)
{
char temp7[11];
strcpy(temp7, p4.job);
if(job != NULL)
delete[] job;
set_new_job(temp7);
parent2::operator=(p4);
return *this; // this line is missing
}
return
语句不是“继承”的。每个应该 return 的功能都必须这样做。
通过这些更改,代码运行:
my name
my name
3
6
3
my name 1
my name 2
some code
一些额外的改进说明:
像 char ch[10001]
这样的数组不能真正成为 C++ 中的函数参数。当它用作参数时,它会默默地衰减到 char *
。因此,您不妨将所有 char ch[10001]
替换为 const char* ch
(更好的是 std::string
),以避免混淆。
此外,分配 temp
数组没有意义。你可以直接做 set_new_name(p1.name)
:
parent1(const parent1 &p1)
{
set_new_name(p1.name);
slr=p1.slr;
age=p1.age;
}
花一些时间熟悉调试器是明智的。不进行调试就几乎不可能创建一个可以工作的应用程序。并启用编译器警告。使用 GCC 使用 -Wall -Wextra
,使用 MSVC - /W4
.
这是使用 std::string
的代码示例。感谢 std::string
我们可以遵循 0:
的规则
class parent1 {
protected:
float slr = 0;
int age = 0;
string name;
void set_new_name(string const &ch) { name = ch; }
public:
parent1() {}
parent1(string const &name, float slr, int age)
: slr(slr), age(age), name(name) {}
string const &get_name() const { return name; }
void print1();
};
void parent1::print1() { cout << get_name() << '\n'; }
class child1 : public parent1 {
protected:
int id = 0;
void set_id(int j) { id = j; }
public:
child1() : parent1() {}
child1(string const &name, float sl, int ag, int j)
: parent1(name, sl, ag), id(j) {}
int get_id() const { return id; }
void print2();
};
void child1::print2() { cout << get_id() << '\n'; }
class parent2 {
protected:
string name1;
string name2;
void set_new_name1(string const &ch) { name1 = ch; }
void set_new_name2(string const &ch) { name2 = ch; }
public:
parent2() {}
parent2(string const &name1, string const &name2)
: name1(name1), name2(name2) {}
string const &get_name1() const { return name1; }
string const &get_name2() const { return name2; }
void print3();
};
void parent2::print3() {
cout << get_name1() << '\n';
cout << get_name2() << '\n';
}
class child2 : public parent2 {
protected:
string job;
void set_new_job(string const &ch) { job = ch; }
public:
child2() : parent2() {}
child2(string const &name1, string const &name2, string const &job)
: parent2(name1, name2), job(job) {}
string const &get_job() const { return job; }
void print4();
};
void child2::print4() { cout << get_job() << '\n'; }
这有效 equally well。
我是 c++ 的新手,最近发现了 classes;
我学习了构造函数、重载运算符、三原则,现在我尝试学习继承。
我创建了 4 classes: 2 parents, 2 childs, 但我在 class parent1
这是class parent1:
class parent1{
protected:
float slr;
int age;
char *name;
void set_new_name(char ch[10001]);
public:
parent1()
{
slr=0.0;
age=0;
name=NULL;
}
parent1(char ch[10001], float sl, int ag)
{
slr=sl;
age=ag;
set_new_name(ch);
}
parent1(const parent1 &p1)
{
char temp[10001];
strcpy(temp,p1.name);
if(name != NULL)
delete[] name;
set_new_name(temp);
slr=p1.slr;
age=p1.age;
}
parent1 &operator=(const parent1 &p1)
{
/// same lines as in copy constructor above
return *this;
}
char* get_name() const;
void print1();
~parent1()
{
delete[] name;
}
};
这是他的childclass,child1:
class child1 : public parent1{
protected:
int id;
void set_id(int j);
public:
child1(): parent1()
{
set_id(0);
}
child1(char ch[10001],float sl, int ag, int j): parent1(ch,sl,ag)
{
set_id(j);
}
child1(const child1 &p2): parent1(p2)
{
set_id(p2.get_id());
}
child1 &operator=(const child1 &p2)
{
set_id(p2.get_id());
parent1::operator=(p2);
}
int get_id() const;
void print2();
};
有class parent 2:
class parent2{
protected:
char *name1;
char *name2;
void set_new_name1(char ch1[10001]);
void set_new_name2(char ch2[14]);
public:
parent2()
{
name1=NULL;
name2=NULL;
}
parent2(char ch1[10001], char ch2[14])
{
set_new_name1(ch1);
set_new_name2(ch2);
}
parent2(const parent2 &p3)
{
char temp2[10001];
strcpy(temp2,p3.name1);
if(name1 !=NULL)
delete[] name1;
set_new_name1(temp2);
/// .. . same lines as above, this time for name2 and p3.name2
}
parent2 &operator=(const parent2 &p3)
{
/// .. same lines as in copy constructor above
return *this;
}
char* get_name1() const;
char* get_name2() const;
void print3();
~parent2()
{
delete[] name1;
delete[] name2;
}
};
还有他的child,child2:
class child2: public parent2{
protected:
char *job;
void set_new_job(char ch3[15]);
public:
child2(): parent2()
{
job=NULL;
}
child2(char ch1[10001], char ch2[10001],char ch3[11]): parent2(ch1,ch2)
{
set_new_job(ch3);
}
child2(const child2 &p4): parent2(p4)
{
char temp6[11];
strcpy(temp6, p4.job);
if(job != NULL)
delete[] job;
set_new_job(temp6);
}
child2 &operator=(const child2 &p4)
{
/// same lines as in copy constructor
parent2::operator=(p4);
}
char* get_job() const;
void print4();
~child2()
{
delete[] job;
}
};
如你所见,class parent1 有 3 种类型的参数(一种浮点型、一种整型和一种字符*)。
Nonte: set_ functions works ok, get_functions just return class parametes (also works ok), print functions just print classes参数(例如:cout << name1;也可以正常工作)
问题是当我在 main 中创建 objects 时,这段代码拒绝工作。 一开始我以为是 operator= 被重载了很多次,结果是 parent1 的 float 参数 主要有:
char ch[10001]="my name", ch1[10001]="my name 1", ch2[14]="my name 2", ch3[11]="some code";
int ag=10;
float sl=10.1;
parent1 o1;
o1=parent1(ch,sl,ag);
o1.print1();
parent1 o2(o1);
o2.print1();
child1 o3;
o3=child1(ch,sl,ag,3);
o3.print2();
child1 o4;
o4=child1(ch,sl,ag,6);
o4.print2();
o4=o3;
o4.print2();
parent2 o5;
o5=parent2(ch1,ch2);
o5.print3();
child2 o6(ch1,ch2,ch3);
o6.print4();
似乎唯一 运行 是:
正在从 parent1 中删除浮点参数;
删除最后一个class; (真不知道为什么最后的class会影响程序)
像这样创建最后一个 object:child2 o6(ch1,ch2,ch3); ,这令人沮丧,因为它应该像其他人一样工作;
我知道我剪的代码很长,但是请,帮助我了解我需要什么解决这个愚蠢的错误!
我发现代码中至少有 3 个问题会导致 crash/undefined 行为。
第一个:
parent1(const parent1 &p1)
{
char temp[10001];
strcpy(temp,p1.name);
if(name != NULL) // name isn't initialized yet,
delete[] name; // these 2 lines shouldn't be here
set_new_name(temp);
slr=p1.slr;
age=p1.age;
}
其次:(这些是启用警告时编译器报告的)
child1 &operator=(const child1 &p2)
{
set_id(p2.get_id());
parent1::operator=(p2);
return *this; // this line is missing
}
第三名:
child2 &operator=(const child2 &p4)
{
char temp7[11];
strcpy(temp7, p4.job);
if(job != NULL)
delete[] job;
set_new_job(temp7);
parent2::operator=(p4);
return *this; // this line is missing
}
return
语句不是“继承”的。每个应该 return 的功能都必须这样做。
通过这些更改,代码运行:
my name
my name
3
6
3
my name 1
my name 2
some code
一些额外的改进说明:
像 char ch[10001]
这样的数组不能真正成为 C++ 中的函数参数。当它用作参数时,它会默默地衰减到 char *
。因此,您不妨将所有 char ch[10001]
替换为 const char* ch
(更好的是 std::string
),以避免混淆。
此外,分配 temp
数组没有意义。你可以直接做 set_new_name(p1.name)
:
parent1(const parent1 &p1)
{
set_new_name(p1.name);
slr=p1.slr;
age=p1.age;
}
花一些时间熟悉调试器是明智的。不进行调试就几乎不可能创建一个可以工作的应用程序。并启用编译器警告。使用 GCC 使用 -Wall -Wextra
,使用 MSVC - /W4
.
这是使用 std::string
的代码示例。感谢 std::string
我们可以遵循 0:
class parent1 {
protected:
float slr = 0;
int age = 0;
string name;
void set_new_name(string const &ch) { name = ch; }
public:
parent1() {}
parent1(string const &name, float slr, int age)
: slr(slr), age(age), name(name) {}
string const &get_name() const { return name; }
void print1();
};
void parent1::print1() { cout << get_name() << '\n'; }
class child1 : public parent1 {
protected:
int id = 0;
void set_id(int j) { id = j; }
public:
child1() : parent1() {}
child1(string const &name, float sl, int ag, int j)
: parent1(name, sl, ag), id(j) {}
int get_id() const { return id; }
void print2();
};
void child1::print2() { cout << get_id() << '\n'; }
class parent2 {
protected:
string name1;
string name2;
void set_new_name1(string const &ch) { name1 = ch; }
void set_new_name2(string const &ch) { name2 = ch; }
public:
parent2() {}
parent2(string const &name1, string const &name2)
: name1(name1), name2(name2) {}
string const &get_name1() const { return name1; }
string const &get_name2() const { return name2; }
void print3();
};
void parent2::print3() {
cout << get_name1() << '\n';
cout << get_name2() << '\n';
}
class child2 : public parent2 {
protected:
string job;
void set_new_job(string const &ch) { job = ch; }
public:
child2() : parent2() {}
child2(string const &name1, string const &name2, string const &job)
: parent2(name1, name2), job(job) {}
string const &get_job() const { return job; }
void print4();
};
void child2::print4() { cout << get_job() << '\n'; }
这有效 equally well。