Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何将参数传递给构造函数?_C++ - Fatal编程技术网

C++ 如何将参数传递给构造函数?

C++ 如何将参数传递给构造函数?,c++,C++,我有一个类a,它由对象B和C组成。如何编写a的构造函数来获取B和C对象?我应该通过值、(常量)引用还是指针传递它们?我应该在哪里解除分配它们 我想到了指针,因为这样我就可以写: A a(new B(1,2,3,4,5), new C('x','y','z')) 但我不知道这是不是一个好的做法。有什么建议吗?通常您通过const reference传递: A a(B(1,2,3,4,5), C('x','y','z')) 这里不需要指针 通常存储值,除非复制效率太低。 然后,类定义如下: cl

我有一个类a,它由对象B和C组成。如何编写a的构造函数来获取B和C对象?我应该通过值、(常量)引用还是指针传递它们?我应该在哪里解除分配它们

我想到了指针,因为这样我就可以写:

A a(new B(1,2,3,4,5), new C('x','y','z'))

但我不知道这是不是一个好的做法。有什么建议吗?

通常您通过const reference传递:

A a(B(1,2,3,4,5), C('x','y','z'))
这里不需要指针

通常存储值,除非复制效率太低。 然后,类定义如下:

class A {
private:
    B b;
    C c;
public:
    A(const B& b, const C& c): b(b), c(c) { }
};

你传递什么取决于你的需要

你需要一份你要传递的东西的副本吗?然后通过常量引用传递

struct A
{
    A(const B& b, const C& c) : m_b(b), m_c(c) {}

private:
    B m_b;
    C m_c;
};
然后像这样建造它:

A myA(B(1,2,3), C(4,5,6));
如果希望
A
对象引用其他
B
C
对象(但不拥有它们),则使用指针(或可能的引用)

我应该通过值、(常量)引用还是指针传递它们

  • 如果对象较大,则按常量引用
  • 如果对象很小,则按值
  • 按常量指针,如果它是可选参数,可以为零(即“NULL”)
  • 如果它是一个可选参数,可以为零,但将由构造类拥有(即解除分配)
  • 请注意,如果您的类有B和C的内部实例,那么通过引用、值或常量引用传递它们很可能涉及使用复制构造函数或赋值运算符。这对于指针来说是不必要的

    A(新的B(1,2,3,4,5),新的C('x','y','z'))

    通常(即不总是)这是一个坏主意,因为:

  • 如果未释放参数,则内存泄漏
  • 若A获得参数的所有权并解除分配,那个么您将无法将堆栈上分配的值作为参数传递。不过,根据您的代码设计,这可能是可以接受的(Qt4经常拥有使用新代码创建的对象的所有权)
  • 我应该在哪里解除分配它们

    最好的办法是确保编译器自动为您释放参数。
    这意味着通过引用、常量引用或值进行传递。或者使用智能指针。

    编辑:这里给出的示例不尊重三巨头的规则(谢谢@Philipp!)。如果按如下所示使用A的定义,则代码将在A的复制构造或A的赋值时崩溃。要正确定义代码,应为A显式定义赋值运算符和复制构造函数(或显式禁止-声明为私有且从未实现)。(结束编辑)

    我应该按价值传递它们吗 (常量)引用,还是指针

    如果A使用B和C,则通过引用或指针将它们保存在A中。要在引用和指针之间进行选择,请参阅如何分配B和C

    如果它们是与A在同一范围内构造的本地堆栈对象,则通过常量引用传递它们

    如果它们是A使用的动态分配对象,则创建自己的对象:通过指针传递它们,并让A的析构函数删除它们

    如果它们是的可选组件,通过指针传递它们(可以为空)

    如果A不负责删除它们,则通过
    *const
    传递它们

    我应该在哪里解除分配它们

    通常在您不再需要它们的地方:)

    如果在A的作用域之外需要它们(如果它们是A使用的外部对象),则在A的作用域完成后删除它们

    如果它们属于A,请在A的析构函数中删除它们。如果指针应该更改,也可以在A的生存期内删除它们

    这里有一个例子,其中B是注入a的可替换组件(由a拥有),C是由a拥有的可选组件(但也注入a)

    (“拥有者”表示A负责删除这两个对象)

    但我不知道这是否是个好主意 实践与否。有什么建议吗

    这真的取决于你,但是你可以像写A(新的B(1,2,4),C(1,2,3))一样简单地写A(新的B(1,2,4),新的C(1,2,3))(在前一种情况下,即没有新代码的情况下,A::b和A::c应该是类内的引用或对象/值,A根本不应该删除它们)


    问题不应该是您是否想要为B和C编写动态分配语句,而是您是否需要这样做。动态分配的速度很慢,如果您对它没有要求,就不应该这样做。

    我希望它拥有它们,所以情况并非如此。谢谢:)您是否需要动态分配对象?否则这就是你的情况。在处理构词时,代码示例提供C++中最简单的最自然的解决方案。我指的是最后一句。正如大多数人所建议的,我将使用const引用。有趣的是,对于
    A
    拥有对象的情况,您和utnapistim提出了不同的解决方案:您提出值,utnapistim提出指针。除了传递原始指针,还有其他方法。例如,案例3为
    Boost.可选
    ,案例4为类似
    Boost::shared_ptr
    的智能指针。那么你就不必处理手动解除分配。我认为重要的是,如果构造函数抛出异常,你就会出现内存泄漏,因为没有人解除分配B和C。使用智能指针的另一个原因:)@Philipp:你能有一个可选的引用吗?我会在案例3中使用
    shared_ptr
    ,在案例4中使用
    auto_ptr
    (除非它实际上是一个数组,在这种情况下,其他智能指针也适用)。@Ben Voigt:除非需要所有权语义转移(用户经常会感到惊讶),否则我不会使用
    auto_ptr
    。如果将指针传递给函数“窃取”它们,可能会造成混乱。关于可选参数,Boost.optional手册说可选的参考是可能的,您可以
    class B;
    class C;
    
    class A
    {
        B* b;
        C* c;
    public:
        A(B* const bb, C* const cc = 0) // cc is optional
        : b(bb), c(cc)
        {
        }
    
        void resetB(B* const bb = 0)
        {
            delete b;
            b = bb;
        }
    
        ~A()
        {
            resetB();
            delete c;
        }
    };
    
    {
        A a(new B, new C);
        a.resetB(); // delete B
        a.resetB(new B); // delete former B and set a new one
    } // both members of A are deleted