脚本宝典收集整理的这篇文章主要介绍了第四节 混合编程、类和对象初识,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
#include <iostream>
using namespace std;
/****************************************************************************************************
* 21.函数的占位参数:C++在声明函数时,可以设置占位参数。占位参数只有参数类型声明,而没有参数名声明。一般情况下,在函
* 数体内部无法使用占位参数,但是又必须传入参数。(了解内容)什么时候用该功能,在后面我们要讲的操作符重载的后置++要用到
****************************************************************************************************/
void testFunc01(int a,int b,int){
//函数内部无法使用占位参数
cout << "a + b = " << a + b << endl;
}
//占位参数也可以设置默认值
void TestFunc02(int a, int b, int = 20){
//函数内部依旧无法使用占位参数
cout << "a + b = " << a + b << endl;
}
void test15(){
//错误调用,占位参数也是参数,必须传参数
//TestFunc01(10,20);
//正确调用
TestFunc01(10,20,30);
//正确调用
TestFunc02(10,20);
//正确调用
TestFunc02(10, 20, 30);
}
/****************************************************************************************************
* 22.函数的重载(overload):同一个函数名在不同场景下可以具有不同的含义。 在c语言中,函数名必须是唯一的,程序中不允
* 许出现同名的函数。在C++中是允许出现同名的函数,这种现象称为函数重载。目的就是为了方便的使用函数名。
* ① 实现函数重载的条件:同一个作用域、参数个数不同、参数类型不同、参数顺序不同;
* ② 返回值不作为函数重载依据,所以参数相同,但返回值类型不同是不被允许的;
****************************************************************************************************/
// 1. 函数重载条件,如命名空间E中的5个函数是不同的函数。
namespace E{
void MyFunc(){ cout << "无参数!" << endl; }
void MyFunc(int a){ cout << "a: " << a << endl; }
void MyFunc(string b){ cout << "b: " << b << endl; }
void MyFunc(int a, string b){ cout << "a: " << a << " b:" << b << endl;}
void MyFunc(string b, int a){cout << "a: " << a << " b:" << b << endl;}
}
// 2. 返回值不作为函数重载依据,所以参数相同,但返回值类型不同是不被允许的。
namespace F{
void MyFunc(string b, int a){}
//int MyFunc(string b, int a){} //无法重载仅按返回值区分的函数,报错
}
// 注意: 函数重载和默认参数一起使用,需要额外注意二义性问题的产生。
void MyFunc(string b){ cout << "b: " << b << endl;}
//函数重载碰上默认参数
void MyFunc(string b, int a = 10){ cout << "a: " << a << " b:" << b << endl;}
void test16(){
// MyFunc("Hello"); //这时,两个函数都能匹配调用,产生二义性,抛出错误:函数调用不明确
}
/****************************************************************************************************
* 23.C和C++混合编程:
* ① 一般一个C文件就需要匹配一个头文件用于在主函数中进行引用,C文件用于函数的定义,头文件用于函数的声明;
* ② 在ubuntu系统中的混合编译,如下:
* step1:gcc -c MyModule01.c -o MyModule01.O // 先把C文件编译成二进制文件
* step2:g++ main.cpp MyModule01.o -o main // 借助于上面生成好的二进制文件,编译生成可执行文件main
****************************************************************************************************/
/* test17()和test18()两种不同的运行方法都可以输出结果
@R_512_688@ _CRT_SECURE_NO_WARNINGS
//#include<iostream>
//using namespace std;
#if 0
#if def __cplusplus
extern "C" {
#if 0
void func1();
int func2(int a, int b);
#else
#include"MyModule01.h"
#endif
}
#endif
#else
extern "C" void func1();
extern "C" int func2(int a, int b);
#endif
void test17()
{
func1();
cout << endl << func2(10, 20) << endl;
}
*/
#include"MyModule01.h"
void test18()
{
func1();
cout << endl << func2(10, 20) << endl;
}
/****************************************************************************************************
* 24.类和对象:把事物的属性和行为抽象地表示成计算机语言,用计算机语言来代表这个事物。
* ① 在C语言中,行为和属性是分开的定义的:定义一个结构体用来表示一个对象所包含的静态属性,定义一个函数用来表示一
* 个对象所具有的动态行为,这样我们就可以抽象地表示出一个事物;
* ② 在C++中,结构体不仅可以定义成员变量(用于定于事物静态属性),还可以定义成员函数(用于定义事物动态行为),这
* 样就可以直接用一个结构体表述一种事物,但是C++中提供了更好的方法描述一个事物就是类;
* ③ 类的封装提供一种能够给属性和行为的访问权限加以控制的机制。类的封装包含两个方面的含义:
* i> 属性和变量合成一个整体,即把变量(属性)和函数(操作)合成一个整体,封装在一个类中;
* ii> 给属性和函数增加访问权限,即对变量和函数进行访问权限控制。
* ④ 另外,类的封装还有以下特点:
* i> 在类的内部(作用域范围内),没有访问权限之分,所有成员可以相互访问;
* ii> 在类的外部(作用域范围外),访问权限才有意义:public,PRivate,protected;
* ---------------------------------------------
* | 访问属性 | 属性 | 对象内部 | 对象外部 |
* ---------------------------------------------
* | public | 共有 | 可访问 | 可访问 |
* | private | 私有 | 可访问 | 不可访问 |
* | protected | 保护 | 可访问 | 不可访问 |
* ---------------------------------------------
* iii> 在类的外部,只有public修饰的成员才能被访问,在没有涉及继承与派生时,private和protected是同等级的,
* 外部不允许访问。
* ④ 类和结构体的区别:class 默认访问权限为private,struct 默认访问权限为public;
* ⑤ 类是抽象的概念,系统不会为它开辟空间,但是它占用空间;
* ⑥ 外部如果想访问私有属性,只有通过类内函数进行访问;
* ⑦ 将成员变量设置为private的好处:
* i> 可赋予客户端访问数据的一致性,即外界可访问的内容一样多,而且能访问的私有数据的方法也就这么多,不可修改
* 且对外都一样。
* ii> 可细微划分访问控制。如果我们设置为private,我们可以实现“不准访问”、“只读访问”、“读写访问”,甚至你可
* 以写出“只写访问”。
* ⑧ 注意:类是抽象概念,不应该在类内对成员变量(属性)进行初始化,这样的话类就是去了它本身的意义,就不能被称作类,
* 而应该被称作个体。
****************************************************************************************************/
/*
// 在C语言中描述一个事物,属性和行为分开定义
tyPEdef struct _Person{
char name[64];
int age;
}Person;
typedef struct _Animal{
char name[64];
int age;
int type; //动物种类
}Ainmal;
void PersonEat(Person* person){ printf("%s 在吃人吃的饭!n",person->name);}
void AnimalEat(Ainmal* animal){ printf("%s 在吃动物吃的饭!n", animal->name);}
#include<string.h>
void test19(){
Person person;
strcpy(person.name, "小明");
person.age = 30;
AnimalEat(&person); //AnimalEat((Animal *)&person);
}
*/
class Person01{
//人具有的行为(函数)
public:
void Dese(Person01 p)
{
cout << "我有钱:" << p.mMoney << "亿" << endl; // 通过类内函数访问类内保护数据
cout << "我年轻:" << p.mAge << "岁" << endl; // 通过类内函数访问类内私有数据
cout << "我身高:" << p.mtall << "cm" << endl; // p.mTall输出178,传入参数值
cout << "有颜有肉,就爱嘚瑟!" << mTall << endl; // mTall输出也是178,传入的参数值,类内数据并没有访问
} // 通过内部函数访问内部属性
//人的属性(变量)
public:
int mTall = 180; // 多高,可以让外人知道,注意:这里不应该出现类内成员变量的初始化操作。
protected:
int mMoney = 10; // 有多少钱,只能儿子孙子知道
private:
int mAge = 18; // 年龄,不想让外人知道
};
void test20(){
Person01 p; // 类的实例化被称为对象
p.mTall = 178;
// p.mMoney 保护成员外部无法访问
// p.mAge 私有成员外部无法访问
p.Dese(p);
}
/* 访问登记设置
class AccessLevels{
public:
int getReadOnly(){ return readOnly; } //对只读属性进行只读访问
void setReadWrITe(int val){ readWrite = val; } //对读写属性进行读写访问
int getReadWrite(){ return readWrite; }
void setWriteOnly(int val){ writeOnly = val; } //对只写属性进行只写访问
private:
int readOnly; //对外只读访问
int noAccess; //外部不可访问
int readWrite; //读写访问
int writeOnly; //只写访问
};
*/
/****************************************************************************************************
* 课堂练习01:设计一个Person类,具有name和age属性,提供初始化函数(Init),并提供对name和age的读写函数(set,get),
* 但必须确保age的赋值在有效范围内(0-100),超出有效范围,则拒绝赋值,并提供方法输出姓名和年龄。(10分钟)
****************************************************************************************************/
#include<string.h>
// 抽象类
class Person02{
private:
char mName[32]; // 定义类不要给成员初始化
char mGender[16];
int mAge;
public:
// 对成员变量mName进行写操作
void setName(char *name){strcpy(mName, name);}
// 对成员变量mName进行读操作
char* getName(void){return mName;}
// 对成员变量mGender进行写操作
void setGender(char *gender){
if (gender == "女" || gender == "男"){
strcpy(mGender, gender);
}else{
cout << "×××××性别输入错误,只能是“男”或“女”!×××××" << endl;
strcpy(mGender, "--");
}
}
// 对成员变量mGender进行读操作
char* getGender(void){return mGender;}
// 对成员变量mAge进行写操作
void setAge(int age){
if (age > 0 && age <= 125){
mAge = age;
}else{
cout << "×××××年龄输入错误,年龄区间为:(0, 125]!×××××" << endl;
mAge = -1;
}
}
// 对成员变量mAge进行读操作
int getAge(void){return mAge;}
// 初始化函数
void initPerson(char *name, char *gender, int age)
{
cout << "输入内容为:" << endl;
cout << "姓名:" << name << endl;
cout << "性别:" << gender << endl;
cout << "年龄:" << age << endl;
setName(name); // strcpy(mName, name);
setGender(gender); // strcpy(mGender, gender);
setAge(age); // mAge = age;
}
// 输出姓名、性别、年龄的方法
void showPerson(void)
{
cout << "最后输入内容为:" << endl;
cout << "姓名:" << getName() << endl;
cout << "性别:" << getGender() << endl;
cout << "年龄:" << getAge() << endl;
}
};
void test21()
{
Person02 per1; // 类的实例化:对象,其中Person02是类名称(抽象的概念),per1是对象实例(实际存在)
per1.initPerson("Lucy", "女", -1);
per1.showPerson();
per1.setAge(16); // 重新设置年龄
per1.showPerson(); // 输出正确结果
}
/****************************************************************************************************
* 课堂练习02:设计长方体类(Cube),求出长方体的表面积(2ab+2ac+2bc)和体积(a*b*c),分别用全局函数和成员函数判断两个
* 长方体是否相等。(10分钟)
****************************************************************************************************/
//立方体类
class Cub{
public:
void setL(int l){ ML = l; }
void setW(int w){ mW = w; }
void setH(int h){ mH = h; }
int getL(){ return mL; }
int getW(){ return mW; }
int getH(){ return mH; }
//长方体表面积
int caculateS(){ return (mL*mW + mL*mH + mW*mH) * 2; }
//长方体体积
int caculateV(){ return mL * mW * mH; }
//成员方法:比较两个长方体是否完全相同
bool CubCompare(Cub& c){
if (getL() == c.getL() && getW() == c.getW() && getH() == c.getH()){return true;}
return false;
}
private:
int mL; //长
int mW; //宽
int mH; //高
};
//全局函数:比较两个长方体是否完全相等
bool CubCompare(Cub& c1, Cub& c2){
if (c1.getL() == c2.getL() && c1.getW() == c2.getW() && c1.getH() == c2.getH()){return true;}
return false;
}
void test22(){
Cub c1, c2;
c1.setL(10);
c1.setW(20);
c1.setH(30);
c2.setL(20);
c2.setW(20);
c2.setH(30);
cout << "c1 面积:" << c1.caculateS() << " 体积:" << c1.caculateV() << endl;
cout << "c2 面积:" << c2.caculateS() << " 体积:" << c2.caculateV() << endl;
//比较两个立方体是否相等
if (CubCompare(c1, c2)){
cout << "c1 和 c2 相等!" << endl;
}else{
cout << "c1 和 c2 不相等!" << endl;
}
if (c1.CubCompare(c2)){
cout << "c1 和 c2 相等!" << endl;
}else{
cout << "c1 和 c2 不相等!" << endl;
}
}
// 主函数
int main()
{
// test15();
// test16();
// test17();
// test18();
// test19();
// test20();
// test21();
// test22();
return 0;
}
// 混合编程:一般一个C文件就需要一个头文件用于被主函数文件进行引入,C文件中用于函数的定义,头文件中用于函数的声明
#include<stdio.h>
#include"MyModule01.h" // 引入C文件的头文件
void func1(){
printf("hello world!");
}
int func2(int a, int b){
return a + b;
}
#ifndef MYMODULE01_H
#define MYMODULE01_H
#if __cplusplus // 宏:是否是C++
extern "C"{ // 外部C文件
#endif
void func1();
int func2(int a,int b);
#if __cplusplus
}
#endif
#endif // MYMODULE01_H
以上是脚本宝典为你收集整理的第四节 混合编程、类和对象初识全部内容,希望文章能够帮你解决第四节 混合编程、类和对象初识所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。