我正在学习C ++继承,但是我有一些问题。 我正在将Zinjal IDE与GNU c ++编译器一起使用。
这是代码:
class String {
protected:
char str[MAX_STR_SIZE];
public:
String(char str_init[])
{
strcpy(str, str_init);
}
};
class PString : String
{
public:
PString(char str_init[])
{
if (strlen(str_init) > MAX_STR_SIZE)
strncpy(str, str_init, MAX_STR_SIZE-1);
else
String(str_init);
}
};
好吧,这只是在创建我自己的“字符串”类。但是:有什么问题?字符串可能会变得太大。因此,当我的“ String”类的构造函数用字符串代替“ MAX_STR_SIZE”(定义为80个字符)调用时,程序将因数组溢出(> 80个字符)而崩溃。 所以我想创建一个名为“ PString”的“子”或“派生”类,它可以处理溢出。 如您所见,PString子类的构造函数将检查字符串是否大于MAX_STR_SIZE。如果它大于char数组可以处理的字符,则将MAX_STR_SIZE截断该字符串,从而避免溢出。如果小于MAX_STR_SIZE,则调用Parent类构造函数。 但是,g ++无法告诉我“没有匹配的函数调用'String :: String()'。
我知道这是一个la脚的错误,但我只是在学习
谢谢。
答案 0 :(得分:1)
您不能只是突然调用构造函数。您只能在特定的地方调用构造函数,而这不是其中之一。
编译器看到String(str_init);
并认为这是一个函数调用,但是您没有匹配的函数-因此出错。
根据下面的评论,这里有一个微妙之处。错误消息是“没有匹配的函数调用'String :: String()”。在名为String
的类中,名为String
的方法将成为构造函数。因此,行String(str_init);
不是函数调用,它正在尝试使用不存在的默认构造函数来创建String
项目。
答案 1 :(得分:-1)
您要尝试执行的操作不需要这套复杂性。通常,strncpy
将正确处理这两种情况。但是,为了教育起见,这里进行一些分析
1。在PString的构造函数中,调用String的构造,并要求将str_intit转换为str。因此,您将导致您想要避免的相同内存损坏。您缺少String()
构造函数。我建议为String创建默认的构造函数,并从PString中删除您使用的那个。
String() {str[0] = 0;}
..
PString(char str_init[])
{
2。您的情况可以作如下修改:
if (strlen(str_init) > MAX_STR_SIZE) {
strncpy(str, str_init, MAX_STR_SIZE-1);
str[MAXLEN-1] = 0; // strncpy will not add '0' in this case. you need to do it yourself
}
else
strcpy(str, str_init);
在上述if子句中,您使用str n cpy是否在'else'之后可以使用简单的strcpy。因此,它看起来像这样:
#include <cstring>
#define MAX_STR_SIZE 80
class String {
protected:
char str[MAX_STR_SIZE];
public:
String(char *str_init)
{
strcpy(str, str_init);
}
String() {
str[0] = 0;
}
};
class PString : String
{
public:
PString(char str_init[])
{
if (strlen(str_init) > MAX_STR_SIZE) {
strncpy(str, str_init, MAX_STR_SIZE-1);
str[MAX_STR_SIZE-1] = 0;
}
else
strcpy(str, str_init);
}
};
答案 2 :(得分:-2)
2个错误。 首先,您需要通过该类的初始化程序列表调用基本构造函数,如本answer所述。
第二,在调用时需要为您的班级分配一些对象
String(str_init);
以下代码在我的计算机上编译。
#include <cstring>
#define MAX_STR_SIZE 20
class String {
protected:
char str[MAX_STR_SIZE];
public:
String(char str_init[])
{
std::strcpy(str, str_init);
}
};
class PString : String
{
public:
PString(char str_init[]) : String(str_init)
{
if (strlen(str_init) > MAX_STR_SIZE)
strncpy(str, str_init, MAX_STR_SIZE-1);
else
String s = String(str_init);
String s2(str_init);
int i = 0;
i++;
}
};