第四节 混合编程、类和对象初识

发布时间:2022-06-08 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了第四节 混合编程、类和对象初识脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
#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(&amp;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;
}

混合编程的两个文件

  1. C语言文件:MyModule01.c
// 混合编程:一般一个C文件就需要一个头文件用于被主函数文件进行引入,C文件中用于函数的定义,头文件中用于函数的声明
#include<stdio.h>
#include"MyModule01.h"    // 引入C文件的头文件

void func1(){
    printf("hello world!");
}
int func2(int a, int b){
    return a + b;
}
  1. C语言文件对应的头文件:MyModule01.h
#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,请注明来意。