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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3201549/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 12:18:18  来源:igfitidea点击:

How to pass parameters to a constructor?

c++

提问by mik01aj

I've got a class A, which consists of objects B and C. How to write a constructor of A that gets B and C objects? Should I pass them by value, by (const) reference, or a pointer? Where should I deallocate them?

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

I thought about pointers, because then I could write:

我想到了指针,因为那时我可以写:

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

But I don't know whether it's a good practice or not. Any suggestions?

但我不知道这是否是一个好习惯。有什么建议?

回答by Philipp

Usually you pass by const reference:

通常你通过 const 引用传递:

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

No need for pointers here.

这里不需要指针。

Usually you store values unless copying is too inefficient. The class definition then reads:

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

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

回答by SigTerm

Should I pass them by value, by (const) reference, or a pointer?

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

  1. By const reference if object is big
  2. by value if object is small
  3. by const pointer if it is an optional argument that can be zero (i.e. "NULL")
  4. by pointer if it is an optional argument that can be zero but will be owned (i.e. deallocated) by constructed class.
  1. 如果对象很大,则通过常量引用
  2. 如果对象很小,则按值
  3. 通过 const 指针,如果它是一个可以为零的可选参数(即“NULL”)
  4. 通过指针,如果它是一个可选参数,可以为零,但将由构造类拥有(即释放)。

Please note that if your class have internal instances of B and C, then passing them by reference, value or const reference, will most likely involve using copy constructor or assignment operator. Which won't be necessary with pointers.

请注意,如果您的类具有 B 和 C 的内部实例,那么通过引用、值或常量引用传递它们,很可能会涉及使用复制构造函数或赋值运算符。指针不需要。

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

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

Normally(i.e. not always) it is a bad idea, because:

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

  1. if A doesn't deallocate arguments, you have a memory leak.
  2. If A takes ownership of arguments and deallocates them, then you won't be able to pass values allocated on stack as arguments. Still, depending on your code design this may be acceptable (Qt 4 frequently takes ownership of objects created with new)
  1. 如果 A 不释放参数,则说明存在内存泄漏。
  2. 如果 A 获得参数的所有权并释放它们,那么您将无法将在堆栈上分配的值作为参数传递。尽管如此,根据您的代码设计,这可能是可以接受的(Qt 4 经常拥有使用new创建的对象的所有权)

Where should I deallocate them?

我应该在哪里释放它们?

The best idea is to make sure that compiler deallocates arguments automatically for you. This means passing by reference, const reference or by value. Or using smart pointers.

最好的办法是确保编译器自动为您解除分配参数。这意味着按引用、常量引用或按值传递。或者使用智能指针。

回答by Peter Alexander

What you pass in depends on your needs.

你传入什么取决于你的需要。

Do you need a copy of the thing you are passing in? Then pass by const-reference.

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

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

private:
    B m_b;
    C m_c;
};

And construct it like this:

并像这样构造它:

A myA(B(1,2,3), C(4,5,6));

If you want your Aobject to refer to some other Band Cobjects (but not own them) then use pointers (or possibly references).

如果你希望你的A对象是指其他一些BC对象(而不是拥有它们),然后使用指针(或可能的引用)。

回答by utnapistim

Edit: The examples given here do not respect the rule of the Big Three (thanks @Philipp!). If the definition of A is used as given below, the code will crash on copy construction for A, or on assignment for A. To define the code correctly, the assignment operator and copy constructor should be explicitly defined for A (or explicitly forbidden - declared as private and never implemented). (end Edit)

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

Should I pass them by value, by (const) reference, or a pointer?

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

If A usesB and C, then hold them by reference or pointer inside of A. To choose between reference and pointer, see how B and C are allocated.

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

If they are local stack objects constructed in the same scope as A, then pass them by const reference.

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

If they are dynamically allocated objects that A uses, make A ownthem: pass them by pointers, and have A's destructor delete them.

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

If they are optional componentsof A, pass them by pointer(that can be null).

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

If A is not responsible of deleting them, pass them by * const.

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

Where should I deallocate them?

我应该在哪里释放它们?

Usually where you no longer need them :).

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

If they are needed past the scope of A (if they are external objects that A uses) then delete them when A's scope is complete.

如果它们需要超出 A 的范围(如果它们是 A 使用的外部对象),则在 A 的范围完成时删除它们。

If they are owned by A, delete them in the destructor for A. It may make sense to also delete them during the lifetime of A, if the pointers should be changed.

如果它们归 A 所有,则在 A 的析构函数中删除它们。如果应该更改指针,在 A 的生命周期内也删除它们可能是有意义的。

Here's an example, where B is a replaceable component injected into A (and owned by A) and C is an optional component owned by A (but injected into A also).

这是一个示例,其中 B 是注入到 A(并由 A 拥有)的可替换组件,而 C 是 A 拥有的可选组件(但也注入到 A 中)。

("owned by" means A is responsible for deleting both objects)

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

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

But I don't know whether it's a good practice or not. Any suggestions?

但我不知道这是否是一个好习惯。有什么建议?

It's up to you really, but you can write A a(B(1, 2, 4), C(1, 2, 3))as easy as A a(new B(1, 2, 4), new C(1,2,3));(in the former case - the one without new - the A::b and A::c should be references or objects/values inside the class, and A should not delete them at all).

这真的取决于你,但你可以写得A a(B(1, 2, 4), C(1, 2, 3))A a(new B(1, 2, 4), new C(1,2,3));(在前一种情况下 - 没有 new - A::b 和 A::c 应该是类中的引用或对象/值,并且 A 不应该删除他们根本)。

The question should not be if you want to write the statement with dynamic allocation for B and C but if you need to. Dynamic allocation is slow and if you don't have a requirement for it you shouldn't do it.

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