简体   繁体   English

C++派生类构造函数

[英]C++ derived Class constructor

I'm learning C++ inheritance and i have some problems with it.我正在学习 C++ 继承,但我遇到了一些问题。 I'm using Zinjal IDE with GNU c++ compiler.我正在使用带有 GNU c++ 编译器的 Zinjal IDE。

This is the code:这是代码:

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); 
    }
};

Well it's just creating my own "string" class.好吧,它只是创建了我自己的“字符串”类。 But: What is the problem?但是:有什么问题? The string can go too much bigger.字符串可以变得更大。 So when the constructor of my "String" Class is called with a string the superssed "MAX_STR_SIZE" (which is defined as 80 chars for expamle) the program will crash with an array overflow ( >80 chars).因此,当我的“String”类的构造函数被一个字符串调用时,被取代的“MAX_STR_SIZE”(在示例中定义为 80 个字符),程序将因数组溢出(>80 个字符)而崩溃。 So i want to create a "child" or "derived" class called "PString" which can handles overflow.所以我想创建一个名为“PString”的“子”或“派生”类,它可以处理溢出。 As you can see PString child Class constructor checks the string if it's > MAX_STR_SIZE.如您所见,PString 子类构造函数检查字符串是否大于 MAX_STR_SIZE。 If it's bigger than what char array can handle it cut off the string by MAX_STR_SIZE, so avoiding the overflow.如果它大于字符数组可以处理的大小,它会通过 MAX_STR_SIZE 截断字符串,从而避免溢出。 If its smaller than MAX_STR_SIZE it calls the Parent class constructor.如果它小于 MAX_STR_SIZE 它调用父类构造函数。 But, g++ fails telling me "No matching function call to 'String::String()'.但是,g++ 没有告诉我“没有匹配的函数调用'String::String()'。

It's a lame error i know, but i'm just learning我知道这是一个蹩脚的错误,但我只是在学习

Thanks in advance.提前致谢。

You can't just call a constructor out of the blue.您不能只是突然调用构造函数。 There are only specific places you can call a constructor and this isn't one of them.只有特定的地方可以调用构造函数,而这不是其中之一。

The compiler sees String(str_init);编译器看到String(str_init); and ssumes it is a function call but you don't have a matching function - hence the error.并假设它是一个函数调用,但您没有匹配的函数 - 因此出现错误。

As per the comment below there is a subtlety here.根据下面的评论,这里有一个微妙之处。 The error message is "No matching function call to 'String::String()".错误消息是“没有匹配的函数调用 'String::String()”。 In a class called String a method called String is going to be a constructor.在一个叫做类String名为方法String将是一个构造函数。 Therefore the line String(str_init);因此行String(str_init); isn't a function call, it is trying to make a String item using a non-existent default constructor.不是函数调用,它试图使用不存在的默认构造函数创建String项。

what you are trying to do does not require this set of complications.您正在尝试做的事情不需要这组并发症。 In general strncpy will handle both cases correctly.通常strncpy会正确处理这两种情况。 However, for the education sake here is some analysis然而,为了教育起见,这里有一些分析

1.In your constructor of the PString you call the construct of the String and ask it to strcpy str_intit into str. 1.在 PString 的构造函数中,您调用 String 的构造函数并要求它将 strcpy str_intit 转换为 str。 So, you cause the same memory corruption you wanted to avoid.因此,您造成了您想要避免的相同内存损坏。 you are missing String() constructor.你缺少String()构造函数。 I suggest to create the default constructor for the String and remove the one you use from PString.我建议为 String 创建默认构造函数并从 PString 中删除您使用的构造函数。

 String() {str[0] = 0;}
 ..
 PString(char str_init[])
 {

2.your case could be modified a bit as the following: 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);

above, in the if clause you use str n cpy whether after the 'else' you can use the simple strcpy.上面,在 if 子句中你使用 str n cpy 是否在“else”之后你可以使用简单的 strcpy。 So, it looks like this:所以,它看起来像这样:

#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 Errors. 2 错误。 First, you need to invoke the base constructor via your class' initializer list as explained in this answer .首先,您需要通过类的初始值设定项列表调用基本构造函数,如本答案中所述

Second you need to assign some object to your class when calling其次,您需要在调用时为您的类分配一些对象

String(str_init); 

The following code compiles on my machine.以下代码在我的机器上编译。

#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++;
    }
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM