代码之家  ›  专栏  ›  技术社区  ›  Martijn Courteaux

编译器抱怨构造函数中变量初始化

  •  1
  • Martijn Courteaux  · 技术社区  · 16 年前

    我在头“test.h”中有一个类的变量,它没有没有没有参数的构造函数。 我有一个这样的构造器:

    Test::Test() // <-- Here he complains:
                 // error: no matching function for call to ‘Beer::Beer()’
    {
       int i = 2;
       theVar = Beer(1, i); // Beer(int, int) is the only constructor
    }
    

    但我是在构造函数体中的(空)初始值设定项列表之后初始化它。

    我怎么解决这个问题?如果这个问题有名字,怎么称呼它?

    谢谢

    4 回复  |  直到 16 年前
        1
  •  14
  •   Stack Overflow is garbage    16 年前

    您需要使用初始值设定项列表。

    Test::Test() : theVar(1, 2) {}
    

    如果问题是 i 是其他函数调用的结果,您可以执行类似的操作

    Test::Test() : theVar(1, compute_i()) {}
    

    问题是构造函数主体被执行 之后 所有成员都已初始化。

    它们首先通过调用初始值设定项列表中指定的任何构造函数进行初始化,如果成员未在其中列出,则通过调用其默认构造函数进行初始化。

    这就是你抱怨错误的原因 Beer::Beer() :因为没有指定其他内容,所以它尝试调用该构造函数来初始化 theVar 它不存在。

    然后 之后 所有成员都已初始化,将执行构造函数体(在其中执行 分配 而不是初始化 泰瓦尔 . 但是编译器永远不会达到这个程度,因为它无法执行初始化。

        2
  •  3
  •   sharptooth    16 年前

    必须为具有参数化构造函数的每个成员变量使用初始值设定项列表:

    Test::Test() :
       theVar( 1, 2 )
    {
    }
    

    如果需要参数在运行时可计算,请使用静态成员函数,并将对它们的调用插入初始值设定项列表。

        3
  •  1
  •   Alexander Gessler    16 年前

    因为编译器将对所有类成员执行默认初始化,所以需要提供一个默认的构造函数。 之前 司机跑了。这是不可避免的。但是,您可以使用c'tor初始值设定项列表来指定自定义c'tor(我假设您知道这一点)。

    一个潜在的解决方法是将这样一个私有的默认任务添加到 Beer 并使 Test 一个朋友 啤酒 以防止其他人意外地呼叫它。

    然而,这是一个设计缺陷。最好的方法是重新设计 Base 它有一个有意义的默认任务,或者重新设计 试验 可以初始化 基地 在初始化器列表中。

        4
  •  1
  •   Alexandre C.    16 年前

    这样写:

    Test::Test() 
        : theVar(1, 2)
    { } 
    

    否则,编译器在进入构造函数体之前尝试用默认的构造函数初始化BEER。在进入构造函数主体之前,必须初始化成员变量。

    您还可以考虑使用一个默认的构造函数,并将beer的成员设置在构造函数体中。