【问题标题】:C++: Can one overload a constructor with a private constructor with the same parameters?C++:可以用具有相同参数的私有构造函数重载构造函数吗?
【发布时间】:2013-02-04 01:28:29
【问题描述】:

可以用具有相同参数的私有构造函数重载构造函数吗?

基本上,如果某个东西存储了一个正整数,那么在公共构造函数中它会确保存储的是一个正整数,而在私有构造函数中它不会执行检查。

很明显这个例子不是一个合适的用法,但有时你想在一个方法中创建一个对象并且你不希望它浪费时间来执行完全安全的初始化;当您稍后要再次执行它们或者它们只是不必要的时候,您可能只想告诉它在没有特殊检查的情况下立即创建一些东西(或者更谨慎的堆分配或一些昂贵的东西),并且类中的方法应该能够自动使用此构造函数,而不是具有相同参数的其他公共构造函数。

【问题讨论】:

  • 我不认为有私有构造函数这样的东西。您可以有一个从构造函数调用的私有方法。您也可以重载构造函数,但它们必须是公共的。
  • @Ben:好的。但这是错误的。您可以拥有私有构造函数。 liveworkspace.org/code/41BKrw$1
  • 我认为官方的说法是 override 而不是 overload。我有时也会犯同样的错误。有些人可能会感到困惑......
  • @Ben,你可以有私有构造函数。一种用途是单身人士。只有朋友/静态成员可以创建。
  • @thang:什么的官方说法是覆盖?由于此功能不存在,因此没有官方说法。但如果它确实存在,我无法想象它为什么会被称为 override,因为该术语通常用于继承上下文中,子类功能替换基类功能。

标签: c++ class constructor overloading


【解决方案1】:

您不能重载私有与公共等访问权限,但您可以重载签名:参数的数量及其类型。

私有构造函数很常见。

一种用法是用于逻辑“删除”的构造函数(最终由 C++11 直接支持),另一种用法是供公共工厂函数使用。


例子:

class A
{
public:
    A( int const x)
    {
        // Whatever, checked construction.
        // Perform the check of the x argument.
        // Then other things.
        // In C++11 it can be done by checking x and forwarding to the
        // unchecked constructor in the same class. Not shown here though.
    }

private:
    enum unchecked_t { unchecked };
    A( int const x, unchecked_t )
    {
        // Unchecked construction.
    }

    // Methods that possibly use the unchecked constructor.
};

【讨论】:

  • 编译器是否从实际的函数调用中删除了额外的参数?你写它的方式,如果你不尝试将整数转换为 unchecked_t 的值,即使你命名它也不能使用额外的参数(或者更确切地说不能用于添加动态逻辑)。
  • @Veltas:你问,一些给定的编译器是否会优化掉额外的参数。与往常一样,答案是衡量是否重要(例如,如果调用是内联的,则可能会发生)。您断言“无法使用额外的参数”,这是不正确的。您进一步断言“即使您命名它”,这是不正确的,有一个命名值。您进一步写“或者更确切地说不能用于添加动态逻辑”,这是毫无意义的。什么是动态逻辑。也许您正在考虑将该参数用于其他东西。不要。
  • 参数未命名。动态逻辑是指无法产生不同的运行时结果,或者更确切地说是编译时可确定的。
  • 我想你现在可以写enum unchecked { },不需要多余的unchecked_t unchecked。虚拟值当然是unchecked()
【解决方案2】:

不,您不能用私有构造函数重载公共构造函数或另一个成员函数:只有名称和参数类型才可用于重载决策。

要执行您要查找的操作,请定义一个私有构造函数,该构造函数接受一个额外的 bool 参数,指示需要执行参数检查:

class A {
public:
    A(int x) : A(x, true) {}
private:
    A(int x, bool check) {
        if (check) {
            // Perform the check of the x argument
        }
    }
};

为了构造一个实例并绕过检查,可以访问私有构造函数的函数调用

A aUnchecked(-123, false);

检查实例以通常的方式构造:

A aChecked(123);

【讨论】:

  • 附加参数的想法很好,为该参数选择bool 类型非常糟糕。我通常使用一些自定义的enum 类型,只有一个可能的值。 struct 也可以解决问题。您不必检查函数体内的值。从论点的存在可以知道,无论该论点表示什么,都已被表示。
  • @Cheersandhth.-Alf 不是 OP 所描述的(选中与未选中):它非常适合。
  • 不,它最不完美。从调用代码中看不到它的作用。还需要在不需要的地方提供愚蠢的论点。此外,运行时检查。哎哟。
  • @Cheersandhth.-Alf 调用代码也是你的代码(第二个构造函数是私有的)——那里绝对没什么可看的。
  • 我不确定这是最大的不完美,但我同意其他答案看起来可能会更好。我提到了检查,但我也注意到实际上我更关心发生的更复杂的事情,比如内存分配和复杂的初始化。我更关心这一点的原因是因为它们实际上会影响性能,而额外的一两次检查则不会(如果检查是微不足道的)。不过还是谢谢你的回答!
【解决方案3】:

使用私有构造函数,您不能直接实例化一个类,而是使用名为 Constructor Idiom 的东西。

你不能继承该类的其他事情,因为要继承的类将无法访问构造函数

你应该做的是创建一个从构造函数调用的方法来检查

【讨论】:

  • 那什么叫构造函数成语呢?
  • class A { static A makeNewA(); };
猜你喜欢
  • 1970-01-01
  • 2011-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-26
  • 2021-11-06
  • 2017-04-30
  • 2010-09-07
相关资源
最近更新 更多