我有很多关于声明和实现的问题,根据大多数(书籍,教程,博客条目),带有构造函数,方法和成员函数的类声明:
class Book
{
public:
Book(const string & author_,
const string & title_,
const string & publisher_,
double price_,
double weight_);
string getName()
{
string name;
name = author + ": " + title;
return name.substr(0, 40);
}
double getPrice();
double getWeight();
private:
string author, title, publisher;
double price, weight;
};
我理解所有的访问级别,构造函数,引用运算符(指针也是!),指针运算符,但是当我读到的东西不那么琐碎如下:
class Type
{
public:
enum TypeT {stringT, intT, doubleT, unknownT};
// 1. which means "explicit"?
// 2. what's ": typeId(typeId_)"? after the Ctor declaration
explicit Type(TypeT typeId_) : typeId(typeId_) {}
// 3. "const" after the declaration which means?
BaseValue * newValue() const
{
return prototypes[typeId]->clone();
}
TypeT getType() const
{
return typeId;
}
static void init();
{
prototypes[stringT] = new Value<string>("");
prototypes[intT] = new Value<int>(0);
prototypes[doubleT] = new Value<double>(0);
}
private:
TypeT typeId;
static vector<BaseValue *> prototypes;
};
我感到迷失,并且确实没有找到关于上述观点的明确信息。
除了回答我的问题,如果你知道他们有这些语言的“伎俩”
答案 0 :(得分:4)
一本很好的C ++入门书应该回答你的问题。
explicit
表示必须在代码中明确提及构造函数,在需要时不能从另一种类型自动构造类型。const
对象上调用该方法。答案 1 :(得分:1)
1)默认情况下,c ++将假设任何采用另一种类型参数的构造函数都可以用作从arg类型到构造函数类型的“隐式转换”;在你的例子中,这将允许你将TypeT传递给任何期望Type的函数,并且构造函数会假设你希望它在实际调用函数之前运行Type(TypeT)构造函数。
explicit
关键字可以防止这种情况发生;它告诉编译器你只需要在专门调用它时运行构造函数。
2)在构造函数的原型和它的主体之间,你可以(并且,在大多数情况下,应该)提供初始化列表;运行构造函数时,系统会在运行构造函数体之前初始化每个父级,然后初始化每个包含的成员。初始化列表告诉编译器您希望在给定成员变量上运行哪个构造函数;在您的示例中,您正在typeId
上运行复制构造函数。
如果您没有在给定成员的初始化列表中提供条目,系统将在输入原始类的主体之前在该成员上运行默认构造函数。这意味着,如果您分配给类构造函数体内的成员,您将两次写入该成员的内存。这有时是必要的,但对于许多情况来说简直是浪费。
3)方法原型末尾的const
向编译器保证,该方法在调用时不会修改类实例中的任何成员变量。这允许在类的const
个实例上调用该方法,就像将const
放在任何保持不变的变量上一样,应尽可能保证正确性和类型安全。
至于要阅读哪些书籍,您问题评论中的链接将是一个很好的起点。既然你似乎理解了语言的准系统基础,我建议从“Effective C ++”开始。它列出了C ++的最佳实践列表,旨在帮助理解该语言的C方面的人。