这是一个非常基础的问题,我已经搜索过了,但我想问问这个社区,我们既有 构造函数
又有 方法
。但通常我们使用构造函数来初始化变量而不是使用方法。我认为两者都可以用于初始化变量。那么它们之间的基本区别是什么?是否有任何坚实的理由呢?
对于初学者来说,请容忍此基础问题。
提前致谢。
这是一个非常基础的问题,我已经搜索过了,但我想问问这个社区,我们既有 构造函数
又有 方法
。但通常我们使用构造函数来初始化变量而不是使用方法。我认为两者都可以用于初始化变量。那么它们之间的基本区别是什么?是否有任何坚实的理由呢?
对于初学者来说,请容忍此基础问题。
提前致谢。
最重要的区别:当您实例化一个对象时,它的构造函数将被调用,而调用方法总是可选的。因此,您可能会忘记调用初始化方法并未能正确地初始化所有内容。
例如,所有这些正常实例化对象的方式都会调用构造函数。
Foo* p = new Foo();
Foo p;
如果您有必填参数,请不要定义默认构造函数,而是要求使用参数进行构造:
class Foo
{
private:
Foo();
public:
Foo(int param1, double param2)
};
这种方式的好处在于你需要在实例化类之前先定义参数。因此你必须要这样做:
Foo* p = new Foo(1, 5.0);
如果使用无效的参数构建失败,则会出现编译器错误:
Foo* p = new Foo(); // compiler error
所以,尽可能地,总是在构造函数中进行初始化。有一些情况下,构造函数可能不可行。例如,唯一的失败构造函数的方法是使用异常。构造失败可能是“例行公事”,并不真正异常。此外,在某些体系结构上,异常可能是昂贵的。另一个情况可能是当您想要确保虚拟方法完全绑定时,这仅在构建后才能保证。
它们不能同时用于初始化成员变量。构造函数负责初始化成员,每当您创建新实例时会自动调用。
考虑以下示例:
class Foo {
public:
// Constructor
Foo() : x(53) // Initialise x
{}
void bar() {
x = 42; // Error, attempt to *assign* a const member!
}
private:
const int x;
};
如果没有构造函数,就没有办法初始化成员变量 x
。
构造函数会自动调用,因此无需担心用户是否已调用初始化方法。然而,Google风格指南确实对构造函数有所规定:
Google的建议是在构造函数中进行简单的初始化,在单独的方法中进行复杂的初始化。
构造函数可用于有效的内存管理,这是函数无法实现的。
析构函数可用于在不需要时销毁构造函数。
此外,使用复制构造函数已知可以防止由于内存错误而导致的困难或错误。
与函数不同,构造函数是在创建对象时自动调用的。此外,构造函数用于表明这是对象初始化的意图。
假设您有一个没有空构造函数的成员变量。那么您唯一的选择就是在构造函数的初始化列表中对其进行初始化。
此外,当您使用new运算符分配数组时,也会调用构造函数,而使用方法进行初始化将使代码更加复杂。
通常,在构造函数中具有复杂逻辑并不是一个很好的想法,但应该在其中进行简单的初始化(确保对象处于某种有效状态所需执行的操作)。
初始化变量无疑是一种非常重要的编程实践。在使用类时,选择将它们初始化在方法内部。因此,我们有两个步骤:
但如果“调用方法”被遗忘,则变量最终会具有垃圾值。为了使程序员更轻松地工作,引入了构造函数方法的概念。
有了构造函数,我们只需要一步:
当创建类的新对象时,“调用部分”会自动执行。