【问题标题】:Initializing reference variables in initialization list在初始化列表中初始化引用变量
【发布时间】:2026-01-12 00:30:01
【问题描述】:

我有三个 .cpp 文件:Game、Guesser 和 Provider。每个头文件都包含其各自的类声明。

在我的 Game 类中,我需要 Guesser 和 Provider 的私有变量。

Guesser 有一个非默认构造函数

Guesser::Guesser (int wordLength, const char* wordListFilename){}

所以我必须通过 Game 构造函数上的初始化列表对其进行初始化。

到目前为止我所拥有的:

Guesser& guesser;

Provider& provider;

`Game::Game(int& wordLength, const char* filename, const Provider& providr) : guesser(wordLength, filename),provider(providr)
{
    numMissedGuesses = 0;
    wordSoFar = string(wordLength, FILL_CHARACTER);
}`

这段代码无法编译,我不知道从哪里开始。

来自编译器的错误消息:

||=== 构建:在 adthangman 中调试(编译器:GNU GCC 编译器)===|

错误:“guesser”声明为引用但未初始化|

错误:'provider' 声明为引用但未初始化|

在构造函数中'Game::Game(int, const char*, const Provider&)':|

错误:表达式列表在 mem-initializer [-fpermissive] 中被视为复合表达式| 警告:逗号运算符的左操作数无效[-Wunused-value]|

错误:从“const char*”类型的表达式中对“Guesser&”类型的引用无效初始化|

错误:从“const Provider”类型的表达式中对“Provider&”类型的引用无效初始化| ||=== 构建失败:5 个错误,1 个警告(0 分钟,0 秒)===|

非常感谢任何帮助。

【问题讨论】:

  • guesser 不应作为参考。
  • 我不能以任何其他方式声明它而不会收到我没有满足构造函数格式的错误。
  • 请发帖MCVE
  • 我对@9​​87654327@ 的最佳猜测是类型不完整。 provider 上的编译器非常清楚。
  • 克里斯,当我这样做时确实提到类型不完整:Guesser guesser;我刚开始学习 C++,所以我不知道该怎么做。我花了两天时间没有用。

标签: c++ class variables reference initialization


【解决方案1】:

guesserprovider 如果要由构造函数初始化,则需要在 class Game { } 范围内声明。

但是,您不能通过向类的构造函数提供参数来初始化对类对象的引用。引用必须由预先存在的对象初始化。 (非成员引用也可以由临时对象初始化,但有点不同。)

此外,引用成员通常是类设计的危险信号。您可能希望对 guesserprovider 使用常规成员对象,而不是引用。

class Game {
    Guesser guesser;
    Provider provider;
};

【讨论】:

  • guesser 和 provider 在类 Game 中声明,它们必须是私有的。我收到“类 'Game' 没有任何名为 'provider' 的字段”错误。
  • @James 我提供了一个将对象声明为类成员的示例。那是你所拥有的吗?因为您描述的所有症状都表明缺少这些声明。请注意,您以后也不要在类之外定义它们。
  • 并且错误:字段 'guesser' 的类型不完整。错误:提交的“提供者”类型不完整。
  • @James 这意味着尚未定义 GuesserProvider 类。它们的定义需要在对象被实例化之前出现。 (但成员函数可以稍后定义。)
  • 据我所知,它们是明确定义的。我只能修改 Game.cpp 和 Game.h 文件。 Guesser 和 Provider 类是为我创建的,所以我实际上只是将 Guesser 类和 Provider 类添加到定义 Game 类的头文件中。
【解决方案2】:

您不能在作为引用的对象上使用构造函数。它本身不是对象,而是指向另一个对象。因此,要么将引用猜测器变量传递给另一个类类型猜测器的对象,要么将其更改为常规变量。您也不能将 const 对象分配给非常量引用。使提供者参数不恒定。

【讨论】:

  • 我可以将 Provider 提供程序创建为常规变量,因为它具有默认构造。我无法将 Guesser guesser 创建为常规变量,因为它会引发错误“没有匹配函数用于调用 Guesser:Guesser();
  • @James 默认构造应该不是问题。当Game 构造函数被调用时,你已经有了构造函数参数。