C++类<一>:类的定义和声明&类的作用域

本文详细介绍了C++中类的基本概念,包括类的定义、构造函数、成员函数及类的作用域等内容,并通过实例说明如何正确使用这些特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一,类的定义和声明.

"最简单地说来,类就是定义了一个新的类型和一个新的作用域"

①定义  

class 类名{

 public:

 private:

};    //分号不能省,因为在分号与右括号之间可以定义多个类对象.

 

②构造函数

创建类类型对象时,编译器会自动使用一个构造体函数来初始化该对象.

构造函数是一个与类同名的成员函数,用于给每个数据成员设置初始值.

 

类名():  data_member1(初始值), data_member2(初始值) {}

 

③成员函数

  成员函数在类内部定义默认为inline,在外部定义的函数必须标明在类的作用域中.

    类型    类名::成员函数(参)  {}

 定义重载成员函数

   同名成员函数只要含有不同类别或不同数量的形参便可实现成员函数重载.

 char get() {  return char; }

 char get(char a) { return a; }

 

二,类的作用域

①使用类的成员.

类的对象或指针分别使用 . 或 -> 来访问成员.

   类对象使用 .         类对象名.成员名

   类指针使用 ->      类指针名->成员名

 

②作用域与成员定义必须指明成员出现在哪个类中:

   double Sale_item::avg_price() const {}

  这样定义,标明了该函数在Sale_item作用域中,在函数的定义体中出现的类的成员可直接引用.

 

④函数返回类型不一定在类作用域中

  class Screen{

 public:

      typedef std::string::size_type index;        //在类定义内部出现对index定义

      index get_cursor() ;

};

 inline  Screen::index Screen::get_cursor() {}   //定义get_cursor()函数

 此处为类定义体的外部,Index是在类定义体内部出现的,所以一定要限定index这个类型是在Screen这个类的作用域中.

&lt;think&gt;首先,用户的问题是关于C++模板的。具体问题是:&ldquo;我想理解C++模板定义为何需要多处使用template&lt;T&gt;声明。请问C++模板为什么需要在每个成员函数前重复使用template&lt;T&gt;?&rdquo; 用户引用了几个参考内容,这些是关于模板定义使用。关键点是: - 引用[1]:展示了模板可以有成员模板函数,并解释了如何定义调用它们。 - 引用[2]:说明了在定义成员函数时,需要添加模板参数列表。 - 引用[3]:解释了模板可以有多个型参数,并且每个型前必须加class。 现在,用户的核心疑问是:为什么在模板中,每个成员函数定义时需要重复使用template&lt;T&gt;。 我的回答需要: 1. 使用中文回答。 2. 结构清晰,帮助用户逐步解决问题。 3. 保证回答真实可靠,基于C++标准。 4. 在行内数学表达式中使用$...$格式,但用户的问题是关于C++代码的,所以可能没有数学表达式。不过,如果有变量或似的东西,我会使用它。 5. 独立公式使用$$...$$,但这里可能不适用。 6. 生成相关问题。 7. 在回答中引用的段落末尾添加引用标识。 用户的问题是关于C++模板的,所以我不需要数学表达式,但如果有代码或变量,我会处理。 关键点:为什么在模板中,成员函数定义时需要重复template&lt;T&gt;。 原因: - 在C++中,模板(template class)是个蓝图,用于生成特定型的。当你在定义成员函数时,编译器需要知道这个函数是模板的部分,所以你必须指定模板参数。 - 语法是:template&lt;typename T&gt; 或 template&lt;class T&gt;,然后定义函数,如 void MyClass&lt;T&gt;::myFunction() { ... }。 - 这是因为成员函数本身依赖于模板参数T,所以它必须在模板上下文中定义。 - 在内部定义成员函数时,不需要重复template&lt;T&gt;,因为整个已经在模板作用域内。但在外部,你需要重新进入模板作用域。 回答结构: 1. 解释模板定义:简要介绍模板是什么。 2. 解释为什么需要重复template&lt;T&gt;:因为成员函数定义时,编译器需要知道它属于模板实例。 3. 使用示例:提供个简单的代码示例来展示。 4. 引用参考内容:用户提供了引用,所以我应该在相关部分添加引用标识。 5. 生成相关问题:在最后添加相关问题。 确保回答真实可靠:基于C++标准,模板定义规则。 最终,添加相关问题。&lt;/think&gt;### C++模板中成员函数定义为何需要重复使用template&lt;T&gt; 在C++中,模板(template class)是种泛型编程机制,允许你定义个通用的蓝图,其中型(如`T`)可以在实例化时指定。例如,定义个模板`MyClass`: ```cpp template &lt;typename T&gt; class MyClass { public: void display(); // 成员函数声明 private: T data; }; ``` 当你在内部定义成员函数时(如内联定义),不需要重复`template&lt;typename T&gt;`,因为整个已在模板作用域内。但如果在**外部**定义成员函数,就必须在每个函数前添加`template&lt;typename T&gt;`(或`template&lt;class T&gt;`)。原因如下: #### 为什么需要重复使用`template&lt;T&gt;`? 1. **编译器需要模板上下文**: 当成员函数定义时,编译器不知道这个函数属于哪个模板实例。添加`template&lt;typename T&gt;`表示该函数是模板的部分,依赖于模板参数`T`。否则,编译器会将其视为普通函数,导致编译错误(如&ldquo;未定义的引用&rdquo;或&ldquo;模板参数缺失&rdquo;)。 例如,在定义`display`函数时: ```cpp // 正确:添加template&lt;typename T&gt;以进入模板作用域 template &lt;typename T&gt; void MyClass&lt;T&gt;::display() { std::cout &lt;&lt; data &lt;&lt; std::endl; } ``` 如果不加`template&lt;typename T&gt;`,编译器无法解析`MyClass&lt;T&gt;::`中的`T`,因为`T`是模板参数,不属于全局作用域[^2]。 2. **成员函数本身是模板化的**: 每个模板的成员函数都隐式地依赖于模板参数。重复`template&lt;typename T&gt;`显式声明了这种依赖关系,确保函数能正确访问型`T`。例如: ```cpp template &lt;typename T&gt; void MyClass&lt;T&gt;::display() { // 这里可以使用T型的数据成员 } ``` 如果省略`template&lt;typename T&gt;`,函数定义中的`T`会变成未定义的标识符,导致编译失败[^1]。 3. **避免二义性**: C++允许模板有普通成员函数模板成员函数(如引用[1]所示)。重复`template&lt;typename T&gt;`帮助编译器区分: - **普通成员函数**:定义时不加`template`,如`void f(int)`。 - **模板成员函数**:定义时加`template`,如`template&lt;typename T2&gt; void f(T2)`。 这确保了重载解析的正确性[^1]。 #### 完整示例 以下代码演示了模板定义成员函数外实现: ```cpp #include &lt;iostream&gt; template &lt;typename T&gt; class Score { public: void Print(); // 声明成员函数 private: T _Math; T _Chinese; }; // 定义Print():必须添加template&lt;typename T&gt; template &lt;typename T&gt; void Score&lt;T&gt;::Print() { std::cout &lt;&lt; &quot;Math: &quot; &lt;&lt; _Math &lt;&lt; std::endl; std::cout &lt;&lt; &quot;Chinese: &quot; &lt;&lt; _Chinese &lt;&lt; std::endl; } int main() { Score&lt;int&gt; scoreInt; // 实例化为int型 scoreInt.Print(); // 输出整数成绩 } ``` - 如果省略`template&lt;typename T&gt;`,编译器会报错:`error: &#39;T&#39; was not declared in this scope`。 #### 总结 - **定义**:不需要重复`template&lt;typename T&gt;`(整个已在模板作用域)。 - **定义**:必须添加`template&lt;typename T&gt;`,以提供模板上下文并解析型`T`[^2][^3]。 - 根本原因:C++的模板机制要求显式声明依赖关系,确保型安全性编译正确性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值