C++补全计划1

本文深入探讨C++编程中的关键概念,包括命名空间、作用域、构造与析构函数等,并介绍了Qt开发中类与对象的应用技巧。

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

这里是C++补全计划,学习Qt 的过程中时,发现C++必须回顾一番


书籍名称:C++ PLUS

前期补充:

关于 using namespace std 的一些注意:、

是用来创建一个名称空间使得函数可以去访问。

让程序访问名称空间std的方法有四种

1.将using namespace std放在函数定义的前面,让文件的所有函数可以使用名称空间std中所有元素。

2.将using namespace std放在特定的函数定义中,让函数可以使用名称空间中所有元素。

3.在特定函数中使用类似using std::cout这样的编译指令,而不是using namespace std,让该函数能够使用特定元素,如cout

4.完全不使用using,而在需要使用名称空间std中的元素时,使用前缀std::。

 

关于namespace的一些资料总结:

为了避免词汇的重复而引发的错误,因此需要一个stdnamespace的库,里面包含了无数的标准函数。使用的时候就像是全局声明一样。

 

 

 

 

#ifdef

程序段1

#else

程序段2

#endif

它的作用是:当标识符已经被定义过(一般是用#define命令定义),则对程序段1进行编译,否则编译程序段2

 

&除了用来指示变量地址,还赋予了用来声明引用。

如:int rate

Int & rodents = rats

&是类型标识符,这里是指向int的引用。

引用和指针还是有一些差别的,在声明的时候引用要将其初始化,而不能像指针那样,先声明再赋值。

函数调用参数时,在变量前追加上地址符号,或者指针,只有这样才能使用到之前赋值给变量里面的值。

产生临时变量的两种情况:

实参的类型正确,但不是左值;

实参的类型不正确,但是可以转换为正确的类型。

左值:可以被引用的数据对象。

应该尽可能使用const:可以避免无意中修改数据的变成错误,使函数能够处理const和非const,否则只能接受非const;使函数能够正确生成并且使用临时变量。

 

引用十分适合结构和类

使用结构引用参数的方式与使用基本变量引用相同,只需要在声明结构参数时候使用引用运算符&即可。

Void se_pc(free_thows & ft); 在函数中将指向该结构的引用作为参数。

 

 

 

第十章:

对象和类

OOP的特性:抽象,封装和数据隐藏,多态,继承,代码重用性

指定基本类完成的三项工作:决定数据对象需要的内存数量,决定如何解释内存的位,决定可使用数据对象执行的操作或方法。

类是一种将抽象转换为用户定义类型的C++工具,它将数据表示和操作的方法组成一个整洁的包。

类两部分组成:

类的声明

类方法的定义

 

开发一个类并编写一个使用它的程序需要许多步骤:通常,将接口(类定义)放在头文件中,并将实现(类方法的代码)放在源代码文件中。

为了识别类,本书遵循一种常见单不常通用的约定,将类名首字母大写。看起来像一个结构声明。

使用类的对象:class socket{};

Stock sally

Stock solly

 

关键字privatepublic描述了对类成员的访问控制。使用类对象的程序都可以直接访问公有部分,但只能通过公有成员(友元函数)来访问对象的私有成员。

  通常,程序员使用私有成员来处理不输于公有接口的实现细节。

实现类成员函数

  数据自动的带有private属性

  (::)作用域解析运算符来标示函数所属的类。

  类方法可以访问private组件

 Void stock::update(double price)

  Stock类的其他成员函数不必使用作用域解析运算符,就可以使用update()

类方法的完整名称:函数的限定名。还有简单的update()是全名的缩写,它只能在类作用域里面使用。

 

内联函数:定义位于声明中的函数都将自动成为内联函数。

修改实现:修改方法实现时,不能影响客户程序的其他部分。

避免科学计数法:

Std::cout.setf(std::ios_base,std::ios_base::floafield)

创建对象,只需要将类名视为类型名:Bozo bozetta

调用:cout<<Bozetta.Retort();

 

类的构造函数和析构函数

为了违背数据隐藏的初衷,还要将类对象初始化,最好在创建对象的时候进行初始化:

Stock gift;

Gift.buy(10,24.25);

但是办不到,不可能什么时候都有这种情况。

为此出现了类构造函数。

 

构造函数的参数表示的不是类成员,而是赋给类成员的值。

C++提供了两种使用构造函数来初始化对象的方法。第一种是显式地调用构造函数,

Stock food=Stock(“....”,250,1.25);

另一种是隐式的调用构造函数:

Stock garment=Stock(“....”,50,2.5)

每次创建类对象时,使用new动态分配内存:

Stock *pstock=new Stock(“”,18,19.0)

调用构造函数是用对象来调用

 

析构函数:用来释放构造函数占用的内存。

原型:~Stock();

 

 

Stock1=stock(“”,10,2.5);

Stock1对象已经存在,因此并不是对着stock1初始化,而是将新值赋予它。

Void stock::show() const

以这种方式声明和定义的类函数被称为const成员函数。只要类方法不修改调用对象,应将其声明为const

函数:const stock & stock::topval(const stock & s) const

This:就是对函数的简写,也就是this->topval()

同时this被限定为const,就不能修改对象的值

 

9

程序分为3部分

头文件,源文件,源代码

编译器只要检查到#ifdenf #define定义了之后,就会直接跳到#endif上一行运行。

 

 

 

 

作用域:描述了名称在文件的多大范围可见。

自动变量的作用域为局部。静态变量的作用域是局部还是全局取决于是如何被定义的。

在函数原型作用域中适应的名称只在包含参数列表的括号内可用。

类声明成员的作用域为整个类。

名称空间中声明的变量只有整个名称空间。

 

用new和C++ delete可以动态开辟,撤销地址空间.在编程序时,若用完一个变量(一般是暂时存储的数组),下次需要再用,但却又想省去重新初始化的功夫,可以在每次开始使用时开辟一个空间,在用完后撤销它.

 

简单地说,那些被virtual关键字修饰的成员函数,就是虚函数。虚函数的作用,用专业术语来解释就是实现多态性Polymorphism),多态性是将接口与实现进行分离;用形象的语言来解释就是实现以共同的方法,但因个体差异,而采用不同的策略。下面来看一段简单的代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

#include<iostream>

using namespace std;

class A

{

    public:

        void print()

        {

            cout<<"This is A"<<endl;

        }

};

 

class B : public A

{

    public:

        void print()

        {

            cout<<"This is B"<<endl;

        }

};

 

int main()

{

    //为了在以后便于区分,我这段main()代码叫做main1

    A a;

    B b;

    a.print();

    b.print();

    return 0;

}

输出结果

分别是“ThisisA”“ThisisB”。通过class Aclass Bprint()这个接口,可以看出这两个class因个体的差异而采用了不同的策略,但这是否真正做到了多态性呢?No,多态还有个关键之处就是一切用指向基类指针或引用来操作对象。那现在就把main()处的代码改一改。

1

2

3

4

5

6

7

8

9

10

11

int main()

{

    //main2

    A a;

    B b;

    A *p1 = &a;

    A *p2 = &b;

    p1->print();

    p2->print();

    return 0;

}

运行一下看看结果,哟呵,蓦然回首,结果却是两个This is A。问题来了,p2明明指向的是class B的对象但却是调用的class Aprint()函数,这不是我们所期望的结果,那么解决这个问题就需要用到虚函数

1

2

3

4

5

6

7

8

9

10

class A

{

    public:

        virtual void print(){cout<<"This is A"<<endl;}

};

class B : public A

{

    public:

    void print(){cout<<"ThisisB"<<endl;}

};

毫无疑问,class A成员函数print()已经成了虚函数,那么class Bprint()成了虚函数了吗?回答是Yes,我们只需在把基类的成员函数设为virtual,其派生类的相应的函数也会自动变为虚函数。所以,class Bprint()也成了虚函数。那么对于在派生类的相应函数前是否需要用virtual关键字修饰,那就是你自己的问题了(语法上可加可不加,不加的话编译器会自动加上,但为了阅读方便和规范性,建议加上)。

现在重新运行main2的代码,这样输出的结果就是This is AThis is B了。

现在来消化一下,我作个简单的总结,指向基类指针在操作它的多态类对象时,会根据不同的类对象,调用其相应的函数,这个函数就是虚函数。

 


### 关于 Dev-C++ 代码自动补全的设置与插件推荐 #### 配置 Dev-C++ 的代码补全功能 Dev-C++ 提供了一些基础的功能来实现代码补全。要启用这些功能,可以通过其内置选项完成配置。打开软件后,在菜单栏找到 `Tools` -> `Editor Options`,进入编辑器选项界面可以调整一些基本设置[^1]。 如果需要更高级别的代码补全体验,则可能需要借助外部工具或者升级至增强版本如 Red Panda Dev C++,该版本改进了原版的一些局限性并增强了对现代化开发需求的支持[^4]。 #### 推荐使用的插件及其作用 对于追求更高效率开发者而言,仅依靠默认机制或许无法满足复杂项目中的需求。以下是几种适用于不同场景下的解决方案: - **YouCompleteMe (YCM)** YCM 是一款非常流行的 Vim 插件,能够提供极其高效的语义级代码提示服务。特别是针对 C/C++ 开发者来说,通过编译 Clang Completer 组件即可获得精准的结果反馈。不过需要注意的是此方法主要面向文本编辑环境而非传统意义上的集成开发平台;因此实际操作前需先确认目标机器已正确安装对应依赖项以及 Python 运行库等必要组件后再执行如下命令以初始化支持: ```bash ./install.py --clang-completer ``` 此外还可以根据个人喜好额外选配其他语言解析引擎进一步扩展适用范围[^3]。 - **vim-easycomplete** 如果偏好统一管理各类形式的建议列表(包括但不限于基于当前文件内容推测得出的可能性词条),那么这款轻量化的替代品也许会成为不错的选择之一。它允许用户自定义触发条件并将多源数据融合进单一按键响应流程当中——只需按下 Tab 键就能快速浏览候选对象集合[^2]。 尽管上述提到的产品均围绕着主流框架构建而成,但由于它们本质上属于第三方附加模块的缘故所以在具体适配过程中难免遇到些许兼容性障碍等问题存在。故而当考虑引入此类技术方案之前务必充分评估潜在风险因素并对后续维护成本有所预期准备才行哦! ```cpp // 示例代码展示如何利用头文件声明函数原型从而辅助IDE理解程序结构以便更好地给出匹配提议。 #include <iostream> void greetUser(); // 声明未定义的方法可以让某些简单的弹窗显示参数信息 int main(){ std::cout << "Hello World!" ; greetUser(); } void greetUser(){ printf("Greetings from custom function!"); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值