当前位置:网站首页 / C++ / 正文

AY的VS2019 的C++11笔记[6] -类入门

时间:2020年07月24日 | 作者 : aaronyang | 分类 : C++ | 浏览: 131次 | 评论 0

右键程序集-添加

 AYUI www.ayjs.net AY 杨洋原创编写,请不要转载谢谢

image.png

image.png

image.png

多了一个.h文件,百度一下 .h和.cpp的区别,其他文章


.h文件是不对外隐藏的, .cpp文件在编译后对外隐藏---这是最本质的特点和区别

.h和.cpp文件本质上是没有什么区别的,.h文件实现的功能是声明本文件或.cpp文件中需要被别人使用或知道的变量、类型、函数及宏定义等。

.h文件就像是一个接口,具体的实现可以在.cpp中也可以在.h中。

.cpp中的函数或变量即便是全局的,在没有其他.cpp文件使用的情况下,也可以不写在.h中

首先,我们可以将所有东西都放在一个.cpp文件内.

然后编译器就将这个.cpp编译成.obj,obj是什么东西?

就是编译单元了.一个程序,可以由一个编译单元组成,

也可以有多个编译单元组成. 如果你不想让你的源代码变得很难阅读的话,

就请使用多个编译单元吧.(一个函数不能放到两个编译单元里面,但两个以上

就可以分别放在一个单元,也就是cpp里面)


    那么就是一个.cpp对应一个.obj,然后将所有的obj链接起来(通过一个叫链接器的程序),

组成一个.exe,也就是程序了.

    如果一个.cpp要用到另一个.cpp定义的函数怎么办? 只需在这个.cpp种写上他的函数声明

就可以了.其余工作由链接器帮你完成,你可以随便调用该函数.

    链接器将所有的obj连接起来,但是如果碰巧有相同的函数或外部变量怎么办?他如何识别?

一般来说是不能允许在同一个程序中,出现两个一样的函数名或外部变量名.

    但是只得庆幸的是,c++可以通过一种叫做链接属性的关键字来限定,你这个函数是属于整个程序

公用的,还是只是在一个编译单元obj里面使用的.

    这些关键字就是extern 和 static; extern是外部链接的意思,也就是除了这个单元,外部的单元

也是能够访问这个函数的.static 是内部链接,自属于自己单元.

说了这么久,还没有说.h的作用呢?

    其实没有.h也能很好的工作,但是当你发现一个外部链接的函数或外部变量,需要许多份

声明,因为c++这种语言,在使用函数和变量的时候,必须将他声明,为何要声明?声明之后才

知道他的规格,才能更好的发现不和规格的部分.你别妄想一个编译单元,会自动从另一个

编译单元那里得到什么信息,知道你是如何定义这个函数的.

    所以说,只要使用到该函数的单元,就必须写一份声明在那个.cpp里面,这样是不是很麻烦,

而且,如果要修改,就必须一个一个修改.这真让人受不了.

.h就是为了解决这个问题而诞生,他包含了这些公共的东西.然后所有需要使用该函数的.cpp,只需要

用#include包含进去便可.以后需要修改,也只是修改一份内容.



请注意不要滥用.h,.h里面不要写代码,.h不是.cpp的仓库,什么都塞到里面.

如果在里面写代码,当其他.cpp包含他的时候,就会出现重复定义的情况,

比如将函数func(){printf};放到头文件a.h,里面还有一些a.cpp需要的声明等;

然后你发现b.cpp需要用到a.cpp里面的一个函数,就很高兴的将a.h包含进来.

注意,#include并不是什么申请指令,他就是将指定的文件的内容,原封不动的拷贝进来.



这时候实际上a.cpp和b.cpp都有一个func()函数的定义.

如果这个函数是内部链接static的话,还好,浪费了一倍空间;

如果是extern,外部链接(这个是默认情况),那么根据在同一个程序内不可出现

同名函数的要求,连接器会毫不留情给你一个连接错误!


不管咯,我们直接先在Box.h文件中定义个类,C++中类,分类定义和类实现两部分,C#直接在一个class里面。

这里只是类定义

#pragma once
class Box
{
public:
    double length;   // 盒子的长度
    double breadth;  // 盒子的宽度
    double height;   // 盒子的高度
};

上方的#pragma once是vs2019新建时候,默认加上去的

#pragma once是一个比较常用的C/C++预处理指令,只要在头文件的最开始加入这条预处理指令,就能够保证头文件只被编译一次。

#ifndef,#define,#endif是C/C++语言中的宏定义,通过宏定义避免文件多次编译。所以在所有支持C++语言的编译器上都是有效的,如果写的程序要跨平台,最好使用这种方式

方式一:

#ifndef _SOMEFILE_H_

#define _SOMEFILE_H_

.......... // 一些声明语句

#endif

方式二:

#pragma once

... ... // 一些声明语句


或者混用

#pragma once

#ifndef __SOMEFILE_H__

#define __SOMEFILE_H__

... ... // 一些声明语句

#endif


除了public,还可以private 或 protected

发现了,访问修饰符只要写一遍,然后加个冒号,class类右花括号有个分号。

image.png

编写测试

image.png

int main()
{
	Box Box1;        // 声明 Box1,类型为 Box
	Box Box2;        // 声明 Box2,类型为 Box
	double volume = 0.0;     // 用于存储体积

	// box 1 详述
	Box1.height = 5.0;
	Box1.length = 6.0;
	Box1.breadth = 7.0;

	// box 2 详述
	Box2.height = 10.0;
	Box2.length = 12.0;
	Box2.breadth = 13.0;

	// box 1 的体积
	volume = Box1.height * Box1.length * Box1.breadth;
	cout << "Box1 的体积:" << volume << endl;

	// box 2 的体积
	volume = Box2.height * Box2.length * Box2.breadth;
	cout << "Box2 的体积:" << volume << endl;



	system("pause");
	return 0;
}

发现代码不用new的,C#需要new

接下来,我们在Box.h中定义几个方法和构造函数,我们上面的例子只定义了3个属性


修改代码:

#pragma once
#ifndef BOX_H
#define BOX_H
class Box
{

private:
    double factor;
public:
    Box();//构造函数
    Box(double factor);//带参数的构造函数
    double PrintVolumn();
    void PrintFactor();
    double length;   // 盒子的长度
    double breadth;  // 盒子的宽度
    double height;   // 盒子的高度

};
#endif

这里定义了3个public的方法,其中2个是构造函数,因为没返回值,名称也跟类名一样

这叫类定义,一般放到.h文件中


接着打开Box.cpp

定义这几个函数的实现,叫类实现

#include <iostream>
#include "Box.h"

using namespace std;

Box::Box(void)
{
	cout << "Box对象创建" << endl;
}
Box::Box(double factor)
{
	this->factor = factor;
	cout << "Box对象创建,factor"<< this->factor << endl;
}
double Box::PrintVolumn()
{
	return height * length * breadth;
}
void Box::PrintFactor()
{
	cout << "PrintFactor,factor=" << this->factor << endl;
}

注意实现的写法

返回类型 类名::函数(其他参数)

这样定义的,C#可以一步到位

无参构造函数的实现,括号需要加void,类定义不用,直接括号就行了。




接下来我们打开main方法的那个文件

我的是test2.cpp

 顶部只需要引入

#include "Box.h"

h文件就行了,项目编译的时候,cpp和h文件会编译在一起,如果#include "Box.cpp"会报错的


demo1,调用默认参数

	Box Box1;        // 声明 Box1,类型为 Box
	Box Box2;        // 声明 Box2,类型为 Box
	double volume = 0.0;     // 用于存储体积

	// box 1 详述
	Box1.height = 5.0;
	Box1.length = 6.0;
	Box1.breadth = 7.0;

	// box 2 详述
	Box2.height = 10.0;
	Box2.length = 12.0;
	Box2.breadth = 13.0;


	cout << "Box1 的体积:" << Box1.PrintVolumn() << endl;
	cout << "Box2 的体积:" << Box2.PrintVolumn() << endl;

image.png

Box Box1时候,调用了默认构造函数,输出Box对象创建,同理的Box2也是


创建Box对象时候,调用指定构造函数的写法

	Box Box3(10);
	Box3.PrintFactor();

实例名,括号,传入参数值

image.png

感觉 类嵌套类,可以看这篇文章


image.png

如上代码可以简化写法

image.png




假如A类中引入了B类的东西,而B类的代码class B在 class A下面,就会报错,因为B还未知

在Class A中,可以写 B *b, 而不是B b,就行


比如下面代码就是报错的

#include 
using namespace std;

class A
{
private:
    B b;
public:
    void doSomething();
};

void A::doSomething()
{ b.doSomething(); }


class B
{
public:
    void doSomething();
};

void B::doSomething()
{ cout<<"OK"<int main(int argc, char *argv[])
{
    A * a = new A;
    a->doSomething();
    return 0;
}



定义析构函数

image.png

然后cpp文件

Box::~Box(void)
{
	cout << "对象被删除了" << endl;
}

运行后,我们按下回车,执行完整个程序,然后3个Box对象在释放内存之前,都执行了析构函数。

image.png


www.ayjs.net 六安杨洋(AY)


 AYUI       www.ayjs.net      AY         杨洋原创编写,请不要转载谢谢

























推荐您阅读更多有关于“C++,”的文章

猜你喜欢

额 本文暂时没人评论 来添加一个吧

发表评论

必填

选填

选填

必填

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

  查看权限

合肥科大智能常年招聘.NET,Java,Web前端,有想找想换工作的私聊我AY唯一QQ:875556003和AY交流

抖音号:wpfui,可以看到我的很多作品效果

AYUI8社区版Github地址:前往获取

作者:杨洋(AaronYang简称AY,安徽六安人)目前是个人,还没公司AY唯一QQ:875556003和AY交流

高中学历,2015年1月17日开始,兴趣学习研究WPF,目前工作繁忙,不接任何活

声明:AYUI7个人与商用免费,源码可购买。部分DEMO不免费.AY主要靠卖技术服务挣钱

不是从我处购买的ayui7源码,我不提供任何技术服务,如果你举报从哪里买的,我可以帮你转正为我的客户,并送demo

查看捐赠

AYUI7.X MVC教程 更新如下:

第一课 第二课 程序加密教程

vs2015 企业版密钥HM6NR-QXX7C-DFW2Y-8B82K-WTYJV

vs2017 企业版密钥NJVYC-BMHX2-G77MM-4XJMR-6Q8QF

标签列表