【问题标题】:Why constructor is used instead of functions?为什么使用构造函数而不是函数?
【发布时间】:2012-03-17 18:03:25
【问题描述】:

这是一个非常基本的问题,我搜索了它,但我只想问这个社区我们有constructorsmethods。但通常我们使用构造函数来初始化变量而不是方法。我认为两者都可以用来初始化变量。那么两者的基本区别是什么。有什么确凿的理由吗? 这是一个非常基本的问题,所以为了初学者水平而忍受它。 提前谢谢..

【问题讨论】:

    标签: c++ function constructor


    【解决方案1】:

    最重要的区别:当你实例化一个对象时,它的构造函数将被调用,而调用一个方法总是可选的。因此,您可能会忘记调用初始化方法并且无法正确初始化所有内容。

    例如,所有这些实例化对象的常规方法都会调用构造函数

    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
    

    因此,只要有可能,总是宁愿在构造函数中进行初始化。在某些情况下,构造函数可能不可行。例如,使构造函数失败的唯一方法是使用异常。构建失败可能是“例行公事”,并不是真正的例外。在某些架构上,例外可能会很昂贵。另一种情况可能是您希望确保虚拟方法是完全绑定的,只有在构造之后才能保证为真。

    【讨论】:

    • 实际上我是在用用户要求的一些值进行初始化,假设出于模拟目的,我们必须将大约 20 个变量初始化为给定值。如果我正确初始化每个变量,那么在这种情况下你会坚持你的论点吗?
    • @kashmirilegion 查看我的编辑。如果您需要初始化 20 个变量,您可以定义一个带有 20 个变量的构造函数或一个带有结构的构造函数。
    【解决方案2】:

    它们不能同时用于初始化成员变量。初始化成员是构造函数的工作,每当您创建新实例时都会自动调用它。

    考虑以下几点:

    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

    【讨论】:

    • 这一切都很好,直到您需要在运行时返回错误代码。 :P
    • +1 为您提供好答案。谢谢你的论点给了我力量,让我们清楚地了解构造函数。
    【解决方案3】:

    构造函数是自动调用的,因此无需担心用户是否调用了初始化方法。但是,Google style guide does have something to say about constructors

    • 除了使用异常之外,构造函数没有简单的方法来发出错误信号。
    • 如果工作失败,我们现在有一个初始化代码失败的对象,所以它可能是一个不确定的状态。
    • 如果工作调用虚函数,这些调用将不会被分派给子类实现。即使您的类当前没有子类化,未来对您的类的修改也会悄悄地引入这个问题,从而引起很多混乱。
    • 如果有人创建了这种类型的全局变量,构造函数代码将在 main() 之前调用,可能会破坏构造函数代码中的一些隐含假设。

    Google 的建议是在构造函数中直接启动,并在单独的方法中进行非平凡的启动。

    【讨论】:

    • 这一切都很好,除非你是不可变对象的粉丝。
    • 遵循 Google 的 C++ 风格指南的主要论据似乎是大名鼎鼎。我完全不喜欢他们对(不)使用异常的看法。如果您不使用异常,则您使用的是非常类似于 C 的 C++ 风格。一位著名的 C++ 专家曾经说过:www2.research.att.com/~bs/3rd_safe0.html 回答您的项目符号列表:(1)然后只需使用异常(您刚刚发现使用构造函数/RAII 必不可少)(2)再次,您不会有无效的object 如果你抛出异常 (3) 我同意,可能会出现一些讨厌的问题,编译器应该警告你。 (4) 那么,构造函数中没有代码?
    【解决方案4】:

    创建对象时会自动调用构造函数,这与函数不同。此外,构造函数用于指示这是用于初始化对象的意图。

    【讨论】:

      【解决方案5】:

      假设您有一个没有空构造函数的成员变量。然后,您别无选择,只能在构造函数的初始化程序列表中对其进行初始化。

      当你用 new 操作符分配一个数组时,也会调用构造函数,而用方法初始化会使代码变得更复杂。

      一般来说,在构造函数中包含复杂的逻辑并不是一个好主意,但应该在那里进行简单的初始化(您需要做的事情是确保您的对象处于某种有效状态)。

      【讨论】:

        【解决方案6】:

        初始化变量无疑是一个非常重要的编程实践。使用类时,选项是在方法中初始化它们。因此,我们有两个步骤:-

        1. 定义方法
        2. 调用方法进行初始化

        但是如果忘记了“调用方法”,变量最终会产生垃圾值。为了让程序员的工作更轻松,引入了构造方法的概念。

        使用构造函数,我们只需一步:-

        1. 定义构造函数

        每当创建类的新对象时,都会自动执行“调用部分”。

        【讨论】:

          【解决方案7】:

          构造函数可用于高效的内存管理,这是函数无法实现的。

          析构函数可用于在不需要时销毁构造函数。

          此外,众所周知,使用复制构造函数可以防止由于内存错误发生而导致的困难或错误。

          【讨论】:

            猜你喜欢
            • 2022-12-18
            • 1970-01-01
            • 2015-06-10
            • 2012-06-28
            • 1970-01-01
            • 2013-04-25
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多