C++;派生类构造函数 我学习C++继承,我有一些问题。 我使用Znimalide IDE和GNU C++编译器。

C++;派生类构造函数 我学习C++继承,我有一些问题。 我使用Znimalide IDE和GNU C++编译器。,c++,inheritance,constructor,C++,Inheritance,Constructor,代码如下: 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) >

代码如下:

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”(对于expamle定义为80个字符),程序将因数组溢出而崩溃(>80个字符)。 所以我想创建一个名为“PString”的“child”或“派生”类,它可以处理溢出。 如您所见,PString子类构造函数检查字符串是否大于MAX_STR_SIZE。如果大于char数组所能处理的大小,则按MAX_STR_SIZE切断字符串,以避免溢出。如果小于MAX_STR_SIZE,则调用父类构造函数。 但是,g++没有告诉我“没有匹配的函数调用'String::String()”

我知道这是个蹩脚的错误,但我只是在学习


提前感谢。

你不能突然调用构造函数。只有特定的地方可以调用构造函数,而这不是其中之一

编译器看到
String(str_init);
并假定这是一个函数调用,但没有匹配的函数,因此出现错误

根据下面的注释,这里有一个微妙之处。错误消息是“没有匹配的函数调用'String::String()”。在名为
String
的类中,名为
String
的方法将成为构造函数。因此,行
String(stru init);
不是函数调用,它试图使用不存在的默认构造函数生成一个
字符串
项。

2错误。 首先,您需要通过类的初始值设定项列表调用基构造函数,如本文所述

第二,调用时需要为类分配一些对象

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++;
    }
};
#包括
#定义最大结构尺寸20
类字符串{
受保护的:
字符str[最大字符大小];
公众:
字符串(char str_init[])
{
std::strcpy(str,str_init);
}
};
类:字符串
{ 
公众:
PString(char str_init[]):字符串(str_init)
{
如果(strlen(str_init)>最大str_大小)
strncpy(str,str_init,MAX_str_SIZE-1);
其他的
字符串s=字符串(str_init);
字符串s2(str_init);
int i=0;
i++;
}
};

您尝试执行的操作不需要这一组复杂情况。一般来说,
strncpy
将正确处理这两种情况。不过,为了教育起见,这里有一些分析

1.在PString的构造函数中,您调用字符串的构造函数,并要求它将str\u intit str复制到str中。因此,您会导致您想要避免的内存损坏。您缺少
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子句中,您使用strncpy,无论在'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);
  }
};
#包括
#定义最大长度80
类字符串{
受保护的:
字符str[最大字符大小];
公众:
字符串(char*str_init)
{
strcpy(str,str_init);
}
字符串(){
str[0]=0;
}
};
类:字符串
{ 
公众:
PString(char str_init[])
{
如果(strlen(str_init)>最大str_大小){
strncpy(str,str_init,MAX_str_SIZE-1);
str[MAX_str_SIZE-1]=0;
}
其他的
strcpy(str,str_init);
}
};

你的代码有几个问题(仅仅编译并不能保证达到预期效果)@Sahi;Dhoked你完全没有抓住要点。如果你像这样调用
字符串
构造函数来输入MAX_stru SIZE+1个字符,你甚至在进入“逻辑”之前就调用了未定义的行为“要处理>最大字符串大小字符以及其他问题,您的
strncpy
调用无法null终止字符串
字符串(STR\u init)
是一个变量声明,变量名周围有多余的圆括号(因此会显示无法找到默认构造函数的消息)。您似乎误读了我的注释。没有临时/匿名字符串