C++学习笔记_02类和对象 2021-04-15

简介: C++学习笔记_02类和对象 2021-04-15
//C++学习笔记_02类和对象 
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
//类和结构体很类似。都用于定义一个数据结构
//类中定义变量(函数)都默认是private
//结构体中            默认是public
class CAnimal
{
    friend void TestFriend(); //授权 TestFriend 这个函数,访问 CAnimal 的私有成员和protected 成员
//private只能在类的成员函数中调用,对象不能直接调用  信息隐藏
private://私有成员:在下面public的函数中,可以直接访问这些变量
    char name[16];        //姓名
    unsigned int  age;    //年龄
    static  unsigned int  count;  //static静态的成员变量  数量 
public://公有成员:对象可以直接调用
    CAnimal();  //构造函数,没有返回值:用于初始化成员变量
    CAnimal(unsigned int age, char szName[]);   //重载构造函数
    ~CAnimal(); //析构函数,没有返回值:用于释放资源
    void Print();
    static unsigned int Count();
private:
    void IncAge();  //私有函数
public:
    unsigned int height; //身高
    static unsigned int cntAge; //静态的成员变量 总年龄
protected: //保护成员:类中可以访问,子类中也可以访问,但是对象不能调用
    void SetAge(int age);//更改年龄 
};
// 函数前面必须加上CAnimal::,表示这个函数是CAnimal这个类中的成员函数
// 不加CAnimal::,这个函数就是一个普通的函数(全局函数)
CAnimal::CAnimal(){
    cout<<"构造 CAnimal-1 ..."<<endl;
    age=0;  //这里就是给 private 里面的 age 赋值
    memset(name, 0, sizeof(name));  //把一段内存数据清0
            //一般,我们使用 malloc 申请一片内存后,memset(p, 0, sz);
            // 特殊用法:memset(p, 0xff, sz) -->内存所有bit位置为1
            // 把p指向的内存段,sz个字节,每个字节都置为为某个值
    count++;
}
CAnimal::CAnimal(unsigned int age, char szName[]){
    cout<<"构造 CAnimal-2 ..."<<endl;
    //age=age; //这个 age 只得是入参age
               //我们要访问private里面定义的age,可以使用 this->age
               //这里this是一个指针,指向的是对象本身
    this->age=age;
    //name=szName; 不允许这样赋值!!!
    strcpy(name,szName);
    count++;
    cntAge += age;
}
CAnimal::~CAnimal(){
    cout<<"析构 CAnimal..."<< endl;
    count--;
    cntAge-=age;
}
void CAnimal::Print(){
    cout<<"Animal Name: "<<name<< endl;
    cout<<"Animal Age : "<<age<< endl;
    cout<<endl;
}
void CAnimal::IncAge(){
    age++;
}
void CAnimal::SetAge(int age){
    this->age = age;
}
//类中的静态成员变量,不可以定义的时候初始化,也不可以在析构函数里初始化
//对于函数中定义的静态变量,函数每次调用的时候,是共用同一个变量
//对于类中定义的静态变量,是每一个对象,共用这个变量
//所以:类中静态变量的初始化方式是:在类的外部直接赋值进行初始化
unsigned int CAnimal::count = 0;
unsigned int CAnimal::cntAge = 0;
unsigned int CAnimal::Count(){
    return count;
}
void TestAnimal(){
    CAnimal A1;  //A1 称之为 CAnimal 的一个对象。 
                 //定义时候,调用构造函数
                 //函数退出,释放资源的时候,会调用析构函数
                 //析构函数是在整个函数执行完毕,return之前调用的 
    CAnimal A2(10, "MokeyA");
    cout << "End of TestAnimal" << endl;
    cout << "A1:" << endl;
    A1.Print();
    cout << "A2:" << endl;
    A2.Print();
    //name 是 private 的成员,不可以通过对象直接访问
    //cout<<"A2 name:"<<A2.name<<endl;   
    //同样的,private 的函数,不可以通过对象直接访问
    //和 age,name 一样,IncAge() 这个函数,
    //只能在类的成员函数中访问,不能通过对象调用
    //A2.IncAge();  
    //protected 的成员,不可以通过对象直接访问
    //A2.SetAge(8);
    //变量定义成pubilc ,可以直接访问
    A2.height = 10;
    //静态变量的访问方式    类名::变量名    
    cout<<"现在 CAnimal 的总年龄:"<< CAnimal::cntAge << endl;
    //这里 count 是私有成员,不能直接 CAnimal::count
    //cout << "现在 CAnimal 对象的个数:" << CAnimal::count << endl;
    //--》定义一个共有函数来访问 Count
    cout<< "现在 CAnimal 对象的个数:"<< A1.Count()<< endl;
    //静态变量,通过对象调用公有函数访问,比较突兀,(容易混淆函数作用)
    //一般情况下,我们可以把 Count() 声明成 静态函数
    //Count声明为静态函数后,我们就可以通过 CAnimal::Count() 来访问
    cout<<"现在 CAnimal 对象的个数:"<<CAnimal::Count()<< endl;
    return;
}
void TestFriend(){
    CAnimal A3(4, "很小的小狗");
    A3.SetAge(6);
    A3.IncAge();
    A3.Print();
    strcpy(A3.name,"很小的大狗");
    A3.Print();
}
void TestStatic(){
    static int x = 0;  //只是在 TestStatic 第一次被调用的时候执行初始化
    x++;
    cout << "static: x = " << x << endl;
}
int main()
{
    CAnimal A0(5, "FishFriend");
    TestAnimal();
    TestStatic();
    TestStatic();
    TestStatic();
    TestFriend();
    system("pause");
  return 0;
}
//2017.03.20  作业 (两个题目二选一):
/*
1: 定义一个学生类Student,包括3个数据成员:
    学号id,姓名name,分数score;
    两个静态数据成员:总分total和学生人数count;
    带参数的构造函数用来初始化对象,
    成员函数ChangeScore用来修改分数,
    静态成员函数GetAverage用来打印计算得到的平均分。
2: 定义一个 会员类 Vip,包含 4 个数据成员:
    会员卡号,会员姓名,会员电话, 会员余额
    +静态成员保存会员总数
   成员函数: 注册会员, 会员充值,会员消费
   要求:注册会员时候,使用静态函数生成一个唯一的会员卡号
*/
相关文章
|
编译器 C++ 容器
【c++11】c++11新特性(上)(列表初始化、右值引用和移动语义、类的新默认成员函数、lambda表达式)
C++11为C++带来了革命性变化,引入了列表初始化、右值引用、移动语义、类的新默认成员函数和lambda表达式等特性。列表初始化统一了对象初始化方式,initializer_list简化了容器多元素初始化;右值引用和移动语义优化了资源管理,减少拷贝开销;类新增移动构造和移动赋值函数提升性能;lambda表达式提供匿名函数对象,增强代码简洁性和灵活性。这些特性共同推动了现代C++编程的发展,提升了开发效率与程序性能。
579 12
|
人工智能 机器人 编译器
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
306 0
|
存储 编译器 程序员
c++的类(附含explicit关键字,友元,内部类)
本文介绍了C++中类的核心概念与用法,涵盖封装、继承、多态三大特性。重点讲解了类的定义(`class`与`struct`)、访问限定符(`private`、`public`、`protected`)、类的作用域及成员函数的声明与定义分离。同时深入探讨了类的大小计算、`this`指针、默认成员函数(构造函数、析构函数、拷贝构造、赋值重载)以及运算符重载等内容。 文章还详细分析了`explicit`关键字的作用、静态成员(变量与函数)、友元(友元函数与友元类)的概念及其使用场景,并简要介绍了内部类的特性。
485 0
|
编译器 C++
类和对象(中 )C++
本文详细讲解了C++中的默认成员函数,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载和取地址运算符重载等内容。重点分析了各函数的特点、使用场景及相互关系,如构造函数的主要任务是初始化对象,而非创建空间;析构函数用于清理资源;拷贝构造与赋值运算符的区别在于前者用于创建新对象,后者用于已存在的对象赋值。同时,文章还探讨了运算符重载的规则及其应用场景,并通过实例加深理解。最后强调,若类中存在资源管理,需显式定义拷贝构造和赋值运算符以避免浅拷贝问题。
|
编译器 C++
类和对象(下)C++
本内容主要讲解C++中的初始化列表、类型转换、静态成员、友元、内部类、匿名对象及对象拷贝时的编译器优化。初始化列表用于成员变量定义初始化,尤其对引用、const及无默认构造函数的类类型变量至关重要。类型转换中,`explicit`可禁用隐式转换。静态成员属类而非对象,受访问限定符约束。内部类是独立类,可增强封装性。匿名对象生命周期短,常用于临时场景。编译器会优化对象拷贝以提高效率。最后,鼓励大家通过重复练习提升技能!
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
编译器 C语言 C++
类和对象的简述(c++篇)
类和对象的简述(c++篇)
|
设计模式 安全 C++
【C++进阶】特殊类设计 && 单例模式
通过对特殊类设计和单例模式的深入探讨,我们可以更好地设计和实现复杂的C++程序。特殊类设计提高了代码的安全性和可维护性,而单例模式则确保类的唯一实例性和全局访问性。理解并掌握这些高级设计技巧,对于提升C++编程水平至关重要。
301 16
|
存储 编译器 C++
类和对象(上)(C++)
本篇内容主要讲解了C++中类的相关知识,包括类的定义、实例化及this指针的作用。详细说明了类的定义格式、成员函数默认为inline、访问限定符(public、protected、private)的使用规则,以及class与struct的区别。同时分析了类实例化的概念,对象大小的计算规则和内存对齐原则。最后介绍了this指针的工作机制,解释了成员函数如何通过隐含的this指针区分不同对象的数据。这些知识点帮助我们更好地理解C++中类的封装性和对象的实现原理。
|
安全 C++
【c++】继承(继承的定义格式、赋值兼容转换、多继承、派生类默认成员函数规则、继承与友元、继承与静态成员)
本文深入探讨了C++中的继承机制,作为面向对象编程(OOP)的核心特性之一。继承通过允许派生类扩展基类的属性和方法,极大促进了代码复用,增强了代码的可维护性和可扩展性。文章详细介绍了继承的基本概念、定义格式、继承方式(public、protected、private)、赋值兼容转换、作用域问题、默认成员函数规则、继承与友元、静态成员、多继承及菱形继承问题,并对比了继承与组合的优缺点。最后总结指出,虽然继承提高了代码灵活性和复用率,但也带来了耦合度高的问题,建议在“has-a”和“is-a”关系同时存在时优先使用组合。
1017 6