声明对象而不调用默认构造函数

查尔斯·德国

我是C ++的新手,并且习惯于使用Java。在Java中,我可以选择声明一个对象而不实例化它,并且希望在C ++中也可以这样做。

假设有一些类Foo,在Java中我可以编写Foo bar;一个声明Foo而无需初始化的实例bar但是,在我编写C ++时Foo bar;bar通过调用class的默认构造函数进行初始化Foo

如果我为一个类编写了一个或多个构造函数,则这尤其令人烦恼Foo,每个构造函数均具有至少一个参数。在这种情况下,代码将无法编译,并显示类似于以下内容的错误no matching function for call to 'Foo::Foo()'

例如,假设我在Java中具有以下类定义:

public class Foo {
    private boolean b;

    Foo(boolean b) { this.b = b; }
}

以及C ++中相应的类定义:

class Foo {
        bool b_;
    public:
        Foo(bool b) : b_(b) {}
};

在Java中,我可以编写一些方法

public static Foo makeFoo(int x) {
    Foo result;
    if (x > 10) { result = new Foo(true); }
    else { result = new Foo(false); }
    return result;
}

但是,如果我用C ++编写类似的方法,则会出现编译错误:

Foo makeFoo(int x) {
    Foo result; // here, a call is made to Foo::Foo() which doesn't exist, and thus compilation fails
    if (x > 10) { 
        result = Foo(true); // this would probably also fail since I didn't specify a copy-constructor, but I'm not entirely sure
    }
    else {
        result = Foo(false); // as above, I think this would probably fail
    }
    return result;
}

尽管我给出的示例没有用,但是在编写Java代码时经常使用这种方法。有没有办法在C ++中模拟这种行为?另外,这只是不好的设计吗?如果是这样,您会推荐哪种方法?

威克

如果您不想像Igor(和其他人)在问题的第一个注释中所说明的那样使用指针来获取参考功能,则可以做几件事。

首先,值类型而不是引用类型的理念是在需要它们之前才创建它们您倾向于在使用该对象以在该函数的其余部分中获得某种多态功能之前声明该引用(可能是某些后期创建通用初始化代码),这是合理的设计,但无法以您编写它的方式表示,因为将涉及创造价值。

您可以提供一个默认的构造函数并为其提供某些行为-但很显然,您和其他任何人都不想被强迫这样做。

替代方法的实质是将变量移到范围内并返回它。

Foo makeFoo(int x) {
    if (x > 10) { 
        Foo result = Foo(true);
        return result;
    }
    else {
        Foo result = Foo(false);
        return result;
    }
}

显然,这会阻止您return之前的if之后编写通用的创建后初始化代码为此,您可以在自己的函数中编写if块,并使其返回结果,然后在初始化对象后编写后续代码。

Foo premakeFoo(int x) {
    if (x > 10) { 
        Foo result = Foo(true);
        return result;
    }
    else {
        Foo result = Foo(false);
        return result;
    }
}

Foo makeFoo(int x) {
    Foo result = premakeFoo(x);
    // common post init code can go here.
    return result;
}

如果您不希望在完全独立的函数中使用它,则可以执行lambda。

Foo makeFoo(int x) {
    Foo result = ([=]() {
        if (x > 10) {
            Foo result = Foo(true);
            return result;
        } else {
            Foo result = Foo(false);
            return result;
        }
    })();
    // common post init code can go here.
    return result;
}

或者,如果您的情况很小,请使用内联三元表达式。

Foo makeFoo(int x) {
    Foo result = (x > 10) ? Foo(true) : Foo(false); // or just Foo(x>10)
    // common post init code can go here.
    return result;
}

还有其他一些涉及模板的聪明选择,但是它们都围绕着为重载的构造函数隔离不同表达式,然后使用赋值来初始化给定一些更复杂表达式的变量的想法。而您想要做的就是获得一个表达式,该表达式以两种不同的方式构造值以覆盖作用域块(跨越if块)。三元和函数是用于在单个表达式中执行if逻辑的选项

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

默认构造函数发布声明值

创建对象实例而不调用超类构造函数

是否保证std :: vector默认构造不调用new?

在构造函数的默认构造对象中未声明变量

C ++如何在不调用构造函数的情况下分配对象

当对象构造函数抛出新表达式时,为什么不调用释放函数?

在调用基类构造函数时声明默认构造函数

使用默认参数而不是默认构造函数调用构造函数

如何创建不调用基础对象的构造函数的ScalaMock存根?

C ++ 11:带有std :: move()的'decltype类实例声明'不调用'move构造函数'。为什么?

为什么不调用move构造函数

Newtonsoft DeserializeObject不调用构造函数

声明没有默认构造函数的字段

连接声明和赋值时,是否不调用默认构造函数?

C ++对象声明,没有默认构造函数(用户声明或隐式声明)

声明成员对象而不调用其默认构造函数

为什么在函数返回时不调用复制构造函数?

为什么此函数不调用move构造函数?

从默认构造函数调用重载的构造函数时,维护对象状态信息

当将对象作为参数传递时,为什么要调用析构函数但不调用构造函数?

在不调用C ++构造函数的情况下实例化对象

声明后调用构造函数

使用匿名对象时,默认构造函数和复制构造函数均未调用

为什么operator *不调用构造函数?

调用对象的构造函数

动态创建的对象(提供其类名作为字符串)不调用其构造函数

程序调用默认构造函数?

为什么在声明指向对象的指针时不调用析构函数

当对象作为参数传递时,为什么不调用我的自定义构造函数?