gpt4 book ai didi

c++ - 尝试学习C++构造函数,为什么在这个例子中构造函数中有一个冒号?

转载 作者:行者123 更新时间:2023-11-30 01:56:32 24 4
gpt4 key购买 nike

template<class T>
Queue<T>::Queue(): frontPtr(NULL), backPtr(NULL), count(0)
{
}

为什么是 Queue(): 而不仅仅是 Queue()

最佳答案

正如其他人评论的那样,: 表示存在初始化列表。您可以在您最喜欢的 C++ 书籍或许多不错的网站中找到更多信息;快速谷歌搜索给了我这篇看起来写得很好的文章:http://www.cprogramming.com/tutorial/initialization-lists-c++.html .

如果您想要初始化列表的简短执行摘要,请看这里:初始化列表可以包含对基类构造函数的调用和对成员变量构造函数的调用。

你为什么想要这样的东西?好吧,很多原因。


请注意,代码相当简单并且包含一些愚蠢的内容(例如 Name 类)。目的只是展示初始化列表的工作原理,而不是编写花哨的代码或利用所有可能的 C++ 功能。


基类的构造

假设您有一个基类,它需要一些参数才能构建。没有其他方法可以将必要的参数传递给它的构造函数,因为在打开构造函数主体的 { 时“执行”(请原谅在这种情况下对“执行”的使用有些松散) 基类已经构建:

class Name
{
const char *name;

public:
Base(const char *n)
{
name = n;
}

const char *getName() const
{
return name;
}
};

class Derived : public Name
{
int a;

public:
Derived(int x)
: Name("Derived")
{
a = y;
}

// Without the call to Name("Derived") in the constructor initializer
// list how could you possibly initialize the base class here?
};

构造类实例成员

同样,也许您的类成员具有需要参数的构造函数。问题是相似的:您可以在哪里调用这些构造函数来传递参数以及如何调用?答案在初始化列表中。让我们扩展之前的示例:

class Name
{
const char *name;

public:
Base(const char *n)
{
name = n;
}

const char *getName() const
{
return name;
}
};

class MyInt
{
int value;

public:
MyInt(int i)
{
value = i;
}

int getInt() const
{
return value;
}
}

class Derived : public Name
{
MyInt a;

public:
Derived(int x)
: Name("Derived"), a(x)
{

}

// Without the call to a(x) in the constructor initializer
// list how could you possibly initialize that member variable
// here?
};

高效初始化成员变量

当您通过将值放在赋值的左侧来手动为变量设置值时,您实际上并不是在“初始化”它。你正在执行一项任务。

这可能是一个有些深奥的差异,但它具有许多重要的含义。其中之一(甚至不是最重要的)是性能。

由于在 C 中,所有基类和所有成员变量的构造函数必须在构造函数主体开始执行之前完成,这可能意味着其中一个构造函数将完成大量工作。当您为这些成员变量之一分配新值时,所有这些工作可能会丢失。

因此,您可以通过在构造函数初始化列表中传递必要的值来初始化成员变量(无论其类型如何)。让我们重写上一个例子:

class Name
{
const char *name;

public:
Base(const char *n)
: name(n)
{
// notice that at this point the member variable "name"
// has already been initialized and can be accessed.
}

const char *getName() const
{
return name;
}
};

class MyInt
{
int value;

public:
MyInt(int i)
: value(i)
{
// Again, note here that the variable "value" already contains
// its value. We need not initialize it again.
}

int getInt() const
{
return value;
}
}

class Derived : public Name
{
MyInt a;

public:
Derived(int x)
: Name("Derived"), a(x)
{

}
};

观察我们如何稍微移动事物的初始化。尽管我们的程序工作方式相同,但现在的行为却大不相同。要了解原因,让我们添加另一个类:

class Name
{
const char *name;

public:
Base(const char *n)
: name(n)
{
// notice that at this point the member variable "name"
// has already been initialized and can be accessed.
}

const char *getName() const
{
return name;
}
};

class MyInt
{
int value;

public:
MyInt(int i)
: value(i)
{
// Again, note here that the variable "value" already contains
// its value. We need not initialize it again.
}

int getInt() const
{
return value;
}
}

class Example : public MyInt
{
const char *type;

public:
Example()
: MyInt(0), type("default")
{
}

Example(int x)
: MyInt(x), type("custom")
{
}

const char *getType() const
{
return type;
}
}

class Derived : public Name
{
Example a;
Example b;

public:
Derived(int x)
: Name("Derived"), a(x)
{

}

void print()
{
std::cout << "This is an " << getName() << " instance" << std::endl;
std::cout << " a has a " << a.getType() << " value" << std::endl;
std::cout << " a=" << a.getInt() << std::endl;
std::cout << " b has a " << b.getType() << " value" << std::endl;
std::cout << " b=" << b.getInt() << std::endl;
}
};

int main(int argc, char **argv)
{
Derived d;

d.print(123);

return 0;
}

关于c++ - 尝试学习C++构造函数,为什么在这个例子中构造函数中有一个冒号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19672000/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com