2D 数组作为默认构造函数参数 C++

2d array as a default constructor argument c++

本文关键字:构造函数 参数 C++ 默认 数组 2D      更新时间:2023-10-16

我在任何地方都找不到答案。

我写了这门课:

class Message {
private:
    char senderName[32];
    char* namesOfRecipients[];
    int numOfContacts;
    char subject[129];
    char body[10001]; 
};

我正在尝试编写一个带有默认参数的构造函数,如下所示:

Message(char senderName[32]="EVA",
        char* Recipents[]={"glados","edi"},
        int numOfRec=3,
        char subject[129]="None",
        char content[10001]="None");

但是,无论我怎么写,它都不会接受收件人默认参数。

甚至可以将 2D 数组作为构造函数的默认参数传递吗?

这么多指针和数组...如果是C++何必呢?只需写:

class Message {
private:
    std::string senderName;
    std::vector<std::string> namesOfRecipients;
    int numOfContacts;
    std::string subject;
    std::string body; 
};

和:

Message("EVA", {"glados","edi"}, 3, "None", "None");

每个人都很开心...

正如保罗所提到的,你应该把namesOfRecipients的声明改为

 char **namesOfRecipients;

然后,您可以在类中拥有一个默认名称的私有 const 静态数组,并使用指向其第一个元素的指针初始化namesOfRecipients。代码如下。

编辑:了解这里的数据语义很重要,例如与Jarod的解决方案相比。默认 ctor 存储指向常量字符串的常量指针数组的地址。完全不可能将不同的字符复制到名称中,或者让数组中的一个指针指向新名称,或者追加名称。这里唯一合法的事情是将 namesOfRecipients 的值替换为指向 char 的新指针数组的指针。

class Message {
private:
    char senderName[32];
    char** namesOfRecipients;
    int numOfContacts;
    char subject[129];
    char body[10001]; 
    static const char* defaultNames[];
    public:
    Message(const char senderName[32]="EVA",
        const char** Recipents = defaultNames,
        int numOfRec=3,
        const char subject[129]="None",
        const char content[10001]="None");
};
const char *Message::defaultNames[] = {"Jim", "Joe"};

你可以执行以下操作:

namespace
{
    char (&defaultSenderName())[32]
    {
        static char s[32] = "EVA";
        return s;
    }
    const char* (&defaultNamesOfRecipients())[2]
    {
        static const char* namesOfRecipients[2]={"glados", "edi"};
        return namesOfRecipients;
    }
}
class Message {
private:
    char senderName[32];
    const char* namesOfRecipients[2];
public:
    Message(char (&senderName)[32] = defaultSenderName(),
            const char* (&namesOfRecipients)[2] = defaultNamesOfRecipients())
    {
        std::copy(std::begin(senderName), std::end(senderName), std::begin(this->senderName));
        std::copy(std::begin(namesOfRecipients), std::end(namesOfRecipients), std::begin(this->namesOfRecipients));
    }
};

但是使用std::string/std::vector会更简单。

使用单独的指针数组(它不是二维数组,尽管它可能看起来像它(作为默认参数:

char* defaultRecipents[] = {"glados","edi"};
class Message {
public:
    Message(char senderName[32]="EVA",
            char* Recipents[]=defaultRecipents){}
};

指定默认数组"内联"不起作用,因为编译器从std::initializer_list的角度"考虑"它,这仅适用于初始化,不适用于声明。抱歉,如果这听起来含糊不清;我对这件事没有足够的经验。

注意:你可能想使用 const 来声明你的字符串,让编译器(和你未来的自己(清楚该类是否会改变字符串:

const char* const defaultRecipents[] = {"glados","edi"};
class Message {
public:
    Message(char senderName[32]="EVA",
            const char* const Recipents[]=defaultRecipents){}
};

在这里,它说const两次声明它不会:

  1. 更改数组元素(例如,将一个数组元素(即字符串(替换为另一个字符串或nullptr(;以及
  2. 更改字符串的内容(例如,在中间剪切一个字符串,或对其进行编辑(