具有初始值的类构造 [英] Class construction with initial values

查看:97
本文介绍了具有初始值的类构造的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是C ++的新手,以及整个课程的想法 - 我还在读一本书来尝试和学习。我读的书说,当我构造一个类,我可以通过这样做:

分配默认值。

  class foo { 
public:
foo(char c,int i);
private:
char exampleChar;
int exampleInt;
};

foo :: foo(char c,int i):
exampleChar(c),
exampleInt(i)
{}

这段代码(对我来说)看起来很乱,不遵循我在其他语言中习惯的规则。 我的问题是,执行上述操作和此操作之间有什么区别?(以下,我个人认为这看起来更清洁)

  foo :: foo(char c,int i){
exampleChar = c;
exampleInt = i;
}

我想到的事情有:性能/效率问题

第一种方式,通过执行

:exampleChar(c),exampleInt(i)被称为初始化列表。



如果你这样做,是默认构造的第一 1 ,然后 您为它们分配一个值。 (当输入构造函数的实际主体时,未被初始化器列表初始化的任何东西都是默认构造的。)这是浪费时间,因为你只是重写值。对于小型类型如 int char 这不是一个大问题,但是当那些成员变量是大类型将需要大量的循环来构造,你一定要使用初始化器列表。



第二种方法不会浪费时间给他们一个默认值,然后覆盖它 - 它会将它们的值直接设置为你给它的值(或者如果成员是一个对象,则调用正确的构造函数)。



你可以看到我们的意思:

  class MyClass {
public:
int _i; //我们的数据

//默认构造函数
MyClass():_i(0){cout< default constructor; }

//构造函数接受一个int
MyClass(int i):_i(i){cout< int constructor; }

//赋值运算符
void operator =(int i){_i = i; cout < 赋值运算符; }
};

class OtherClass {
public:
MyClass c;

OtherClass(){
c = 54;
}
};

OtherClass oc;

您会看到

 默认构造函数
赋值运算符



如果您将 OtherClass 的构造函数更改为其他类的构造函数,

  OtherClass():c(54){} 

您会看到

  int constructor 

。只有一个调用相比两个。



初始化列表也是必须的


  1. 有没有默认构造函数的类型。你必须在初始化器列表中调用正确的构造函数。


  2. 有一个 const 给定一些值(而不是永久地具有默认值


  3. 有一个引用成员必须使用初始化列表。

    li>

tl; dr:做到这一点,因为它至少和其他方式一样快,但从不慢,有时更快。

1 对于类似 int char ,它们实际上不是构造的;它们只是具有之前发生的任何内存的值。


I'm new to C++, and the whole idea of classes - I'm still reading a book to try and learn. The book I'm reading says that when I construct a class, I can assign default values by doing this:

class foo {
public:
   foo(char c, int i);
private:
   char exampleChar;
   int exampleInt;
};

foo::foo(char c, int i):
exampleChar(c),
exampleInt(i)
{}

This code (to me) looks very messy, and doesn't follow rules that I'm used to in other languages. My question is, what's the difference between doing the above, and this (below, which I personally think looks a lot cleaner)?

foo::foo(char c, int i) {
   exampleChar = c;
   exampleInt = i;
}

Sort of things I'm thinking about are: are there performance/efficiency issues if done on a large scale - or is it exactly the same?

解决方案

The first way, by doing : exampleChar(c), exampleInt(i) is called an initializer list.

If you do it the second way, the two variables are default constructed first1, then you assign them a value. (When the actual body of the constructor is entered, anything that hasn't been initialized by the initializer list is default constructed.) This is a waste of time because you're just overwriting the values anyway. For small types like int or char this isn't a big deal, but when those member variables are large types that would take lots of cycles to construct, you definitely want to use the initializer list.

The second way won't waste time giving them a default value and then overwriting it - it will set their values directly to that value you give it (or call the right constructor if the member is an object).

You can see what we mean by doing this:

class MyClass {
public:
    int _i; // our data

    // default constructor
    MyClass() : _i(0) { cout << "default constructor"; }

    // constructor that takes an int
    MyClass(int i) : _i(i) { cout << "int constructor"; }

    // assignment operator
    void operator=(int i) { _i = i; cout << "assignment operator"; }
};

class OtherClass {
public:
    MyClass c;

    OtherClass() {
        c = 54;
    }
};

OtherClass oc;

You'll see that

default constructor
assignment operator

is printed. That's two function calls which, for other classes, could be expensive.

If you change the constructor of OtherClass to

OtherClass() : c(54) {   }

You'll see that

int constructor

is printed. Just one call compared to two. This is the most efficient way.

Initializer lists are also a must when you

  1. have types that have no default constructor. You have to call the right constructor in the initializer list.

  2. have a const member that you want to give some value (rather than just have permantently the default value

  3. have a reference member. You must use initializer lists on these.

tl;dr: do it because it's at least as fast but never slower than the other way, and sometimes far faster.

1 For built in types like int and char, they are actually not constructed at all; they just have the value of whatever memory they happen to have had previously.

这篇关于具有初始值的类构造的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆