c++面向对象程序设计总结(类的使用)

本篇算是学习c++有关类的知识的一些易错点吧.....

并不是特别详细

几点并不关于类的东西

1.函数模板,用虚拟类型来实现模板的功能

#include<iostream>
using namespace std;
template <typename t>//t为虚拟类型的名字,自己起的
t maxx(t a,t b,t c)
{
    return max(a,max(b,c));
} 

int main()
{
    double a=1.1,b=2.2,c=3.3;//不管为double 还是int都可以调用maxx
    cout<<maxx(a,b,c)<<endl;
    int a1=1,b1=2,c1=3;
    cout<<maxx(a1,b1,c1)<<endl;
 } 

2.关于函数默认的参数值要放到最右边

void f1(float a,int b=0,int c,char d=‘a‘);//错误,
void f2(float a,int c,int b=0,char d=‘a‘);//正确 

3.内置函数

函数最左边加上inline(我觉得没啥用),规模很小的函数才用

4.字符串

sizeof(string) 为4,因为系统分配的是固定的字节数,存放的是字符串的地址

.......(以后再补充把)

开始类的学习

1.三种类的类型

public

这个就不多说了,类的对外接口

private

想要访问只能通过该类中的函数来访问

protected

和private差不多,区别在于继承时,以后说

2.类的声明和成员函数的分离(以后更新)

3.构造函数

没有返回值,名字和类名字一样#include<iostream>

using namespace std;
class box{
    public:
        box(int ,int ,int );//构造函数 (有无默认参数都行)
        int volume();
    private:
        int h;
        int w;
        int l;
};
box::box(int a,int b,int c)
{
    h=a,w=b,l=c;
}
//其实一般这样写
// box::box(int a,int b,int c):h(a),w(b),l(c){}//注意如果是数组的话  则要写在大括号内//box::box(int a,int b,int c,char nam[]):h(a),w(b),l(c)//{strcpy(name,nam);}

可以用另一个对象初始化另一个

time t1;

time t2=t1;   //注意是吧t1的数据成员复制到t2,而不调用t2的构造函数

4.析构函数

注意一点,先构造的后析构,相当于栈,先进后出

静态局部对象,在函数结束时,并不释放,也就不调用析构函数

5.对象数组

box b[3] = (1 , 2 ,3)//这样其实不对,这三个实参则分别作为3个元素的第一个实参

初始化应该

box a[3]={
    box(10,20,30);
    box(20,30,40);
    box(1,2,3);
}

6.对象指针

先说下函数指针。。。。还有函数指针????

类型名(* 指针变量名)(参数列表)

void (* p)();//p是一个指向void型函数的指针
p=fun;//fun函数入口地址付给p 注意没有括号
(*p)();

对象成员函数有些复杂

要求    函数参数类型和个数匹配        函数返回值类型一样     所属的类一样

void ( time:: *p )();//此时p为指向time类中的成员函数指针

time t;
 void (time:: *p)();
 p = &time::gettime();
 (t.*p)();

7.this指针(指向当前对象)

当前被调用的成员函数所在对象的起始地址

int box::volume()
 {return (h*l*w);}//实际为{ return this->h * this->l * this->w;}

调用时 如 a.volume() ,实际为将对象a的地址传给形参this指针

8.常对象
只能通过构造函数参数表来对其初始化,所有数据成员绝对不能被改变,并且只能调用它的常成员函数
如果非要改变,要加上 mutable 如有一个计数变量count, 则要 mutable int count;

非const数据成员 非const函数可引用和改变 const函数可引用不可改变
const数据成员 非const函数可引用不可改变 const函数可引用不可改变
const函数不可调用非const函数

常指针 如
Time t1;
Time * const p = =&t1;
p不可再改变
常变量只能被常指针指向,,
普通变量也可被常指针指向,但这时该普通变量就在这期间变成的常变量,不能改变

复制构造函数
Box box2(box);

9.静态数据成员

数据声明前 加 static
特点是可以被每个该同类对象所引用,只能在类体外进行初始化,在类外也可直接引用
如 int Box::height = 10;//不必加static
可以通过对象名来引用,也可以通过类名

cout<<a.count<<endl;
cout<<Box::count<<endl;

10.友元
友元函数可以使一般的,也可以是另一个类中的,可以访问私有数据成员
友元类就是全家都是友元函数
注意是单向的,注意不能传递

11.类的模板

temple<class t>//t 为虚拟变量名字 可以有多个,但都要加class 如:temple<class t1,class t2>
class compare{
public:
compare(t a,t b)
{
x=a,y=b;
}
t max() {
return max(a,b);
}
private:
t x,y;
}; 

定义对象时为:
compare<int> cmp(3,4);
//多个时 compare<int ,double> cmp(3,4);

12.对运算符的重载

class yuan{
    public:
        yuan(double a,double b):x(a),y(b){};
        yuan operator +(yuan &t)
        {
            return yuan(x+t.x, y+t.y);
        }
    private:
        double x,y;
};             

此时如果有
yuan c1(1,2),c2(1,2),c3;
c3 = c1 + c2;
则实际为 c3 = c1.operator(c2);

但其实我觉得更方便的是通过友元函数

class yuan{
    public:
        yuan(double a,double b):x(a),y(b){};
        friend yuan operator +(yuan &t1,yuan &t2)//这个其实挺灵活的,可以自行改变
        {
            return yuan(t1.x+t2.x, t1.y+t2.y);
        }
    private:
        double x,y;
};             

c3 = c1 + c2 则解释为operator +(c1,c2);

13.继承

派生类拥有基类的数据成员,其分配如下

先说公有继承

基类属性                               派生类

private                                  不可访问

public          公有继承后        public

protected                            protected

私有继承

基类属性                               派生类

private                                  不可访问

public          私有继承后        private

protected                            private

保护继承

保护成员:只有子女(派生类)可以访问,(友元函数也不行)

基类属性                               派生类

private                                  不可访问

public          保护继承后        protected

protected                            protected

14.有子对象的派生构造函数

#include<iostream>
using namespace std;
class Student{
    public:
        void display();
        Student(int n,string nam):num(n),name(nam){}
    protected:
        int num;
        string name;
};
class Student1: public Student{
    public:
        Student1(int n,string nam,int n1,string nam1,int a,string ad):
            Student(n,nam),monitor(n1,nam1),age(a),addr(ad){}//注意初始化,一般用初始化表来 ,同样的,在多级派生中也是如此来构造
        void show()
        {
            monitor.display();
        }
    protected:
        Student monitor;//派生类中的子对象
        int age;
        string addr;
};
int main()
{

 } 

多级的形式

派生类构造名: 基类1构造函数(参数表) , 基类2构造函数(参数表) , 基类3构造函数(参数表)

{  派生类中新增的数据成员初始化语句 }

15 . 关于多重继承的二义性问题

就是继承的函数名  和   派生的函数名一样了

假设有类A和类B,此时类C同时继承类A和类B,现在问题是  类A 类B  类C都有一个  叫display()的函数

C c1;

c1.display()//此时该是谁呢,是最新的也就是c的display()。这个会覆盖

此时要想访问A的display(),则要限定作用域 。

比如  c.A::display();

16.虚基类

D 是 B 和 C 的派生类,B 和 C 又都是继承了A,这样会保留多份数据成员的拷贝

虚基类是的在继承简介共同基类时只保留一份

class A
{
    A(int i){}
    .....
};
class B: virtual public A
{
    B(int n):A(n){}
    ...
};
class C: virtual public A
{
    C(int n):C(n){}
    ...
};
class D:public B,public C
{
    D(int n):A(n),B(n),C(n){}//这个必须由最后的派生类中对直接基类和虚基类初始化
}

17.类型的转化

派生类可以向基类对象赋值  (大材小用),也可以向积累对象的引用进行赋值或初始化

派生类对象的地址可以赋给基类对象的指针变量,也就是说,指向基类对象的指针变量也可以用来指向派生类对象

18.多态性

分为两种 ,静态多态性和动态多态性(啥玩意啊,玩的怪花(小声bb))

静态多态性 就是  函数重载   和运算符的重载

动态  就是通过虚函数来实现的

说一下虚函数,作用还是要解决继承中的二义性问题,

解决方法是想通过指针的方法来实现

Student stu(...);
Graduate grad(...);//假设grad是stu的派生,且两者都有display函数
Student *p = &stu;
p->display();
p = &grad;//想通过变换指针指向来,但单单的这样做是不行的,因为这样做会把grad类型强制转化成student的类型
p->display();

解决上述问题的方法是将Student类中的display()函数前加上virtual

  注意问题是  成原函数 定义为虚函数后,其派生类都为虚函数

  使用方法是指向一个基类对象的指针变量,并使它指向同一类族中需要调用该函数的对象

 

19.虚析构函数

如下面代码

class Point{
    public:
        point();
        ~point();
};
class Circle: public Point
{
    public:
        Circle();
        ~Circle();
}
int main()
{
    Point *p = new Circle;
    delete p;
    return 0;
}

new的一个对象,在释放的时候,只会执行基类的析构函数,而不执行派生类的

解决方法是  在Point 的析构函数前加上 virtual

个人理解(这个virtual  在继承中 都会遗传)

20.纯虚函数

先说一点吧,往往有一些类,他们不用来生成对象,唯一目的就是用它去建立派生类,叫做抽象类

比如,点 可以派生出 园 ,圆可以派生出圆柱体  ,但这些都是 shape 的直接派生或者间接派生

比如

class Shape{
    public:
        virtual float area() const {return 0.0;}//虚函数
        virtual float volume() const {return 0.0;}//虚函数
        virtual void shapeName() const = 0; // 纯虚函数 形式为 virtual 函数类型 函数名字 (参数列表) =0;
};

最后来个差不多的

#include<iostream>
using namespace std;
class Shape
{
    public:
        virtual float area() const {return 0.00;}
        virtual float volume() const {return 0.00;}
        virtual void ShapeName() const = 0;
};
class Point: public Shape
{
    public:
        Point(float a=0,float b=0): x(a), y(b){};
        void SetPoint(float a,float b)
        {
            x=a,y=b;
        }
        float getX() const {return x;}
        float getY() const {return y;}

        virtual void ShapeName() const {cout<<"point"<<endl;}
        friend ostream &operator <<(ostream &,const Point &);
    protected:
        float x,y;
};
ostream &operator <<(ostream &output,const Point &p)
{
        output<<"["<<p.x<<","<<p.y<<"]"<<endl;
        return output;
}
class Circle: public Point
{
    public:
        Circle(float x=0,float y=0,float r=0):Point(x,y),radius(r) {}

        void SetRaidus(float r){ radius = r;}

        float GetRadius() const {return radius;}

        virtual float area() const{ return 3.14 * radius * radius;}

        virtual void ShapeName() const {cout<<"Circle"<<endl;}

        friend ostream &operator <<(ostream &,const Circle &);
        protected:
            float radius;
};
ostream &operator <<(ostream &out,const Circle &c)
{
    out<<"["<<c.x<<" "<<c.y<<"]"<<endl;
    out<<"r="<<c.radius<<endl;
    return out;
}
class Yuan: public Circle
{
    public:
        Yuan(float x=0,float y=0,float r=0,float h=0):Circle(x,y,r),height(h){}

        void SetHeight(float h) {height = h;}

        virtual float area() const {return 2 * Circle::area() + 2 * 3.14 * radius * height;}

        virtual float vulume() const {return Circle::area() * height;}

        virtual void ShapeName() const {cout<<"Yuan"<<endl;}

        friend ostream &operator <<(ostream &,const Yuan &);
    protected:
        float height;
};
ostream & operator <<(ostream &out,const Yuan &Y)
{
    out<<"["<<Y.x<<" "<<Y.y<<"],r="<<Y.radius<<"H="<<Y.height<<endl;
    return out;
}

int main()
{
    Point point (3.2,4.5);
    Circle circle(2.4,1.2,5.6);
    Yuan yuan(3.4,6.4,5.2,10.5);
    point.ShapeName();
    cout<<point<<endl;

    circle.ShapeName();
    cout<<circle<<endl;

    yuan.ShapeName();
    cout<<yuan<<endl;

    Shape *pt;
    pt=&point;
    pt->ShapeName();

    pt=&circle;
    pt->ShapeName();
    pt=&yuan;
    pt->ShapeName();
    return 0;
}

可能以和还会更新吧..............

原文地址:https://www.cnblogs.com/wpbing/p/9774818.html

时间: 2024-10-11 08:32:37

c++面向对象程序设计总结(类的使用)的相关文章

python面向对象程序设计(类成员)第二节

python 面向对象程序设计(类成员) 目录: (1)        类成员和实例成员 (2)        公有成员和私有成员 (3)        方法 (一)类成员与实例成员: 实例属性属于实例(对象),只能通过对象名访问. 类属性属于类,类名或对象名都可以访问,属于类的数据成员是在类中所有方法之外定义的. class Car:     price = 1000   #类属性     def __init__(self,c):         self.color = c car1 =

Python基础(16)_面向对象程序设计(类、继承、派生、组合、接口)

一.面向过程程序设计与面向对象程序设计 面向过程的程序设计:核心是过程,过程就解决问题的步骤,基于该思想设计程序就像是在设计一条流水线,是一种机械式的思维方式 优点:复杂的问题的简单化,流程化 缺点:扩展性差 面向对象的程序设计:核心是对象,对象是特征(变量)与技能(函数)的结合体,是一种上帝式的思维方式 优点:解决了程序的扩展性 缺点:可控性差 二.类和对象 以游戏举例,基于面向对象设计一个款游戏:英雄联盟,每个玩家选一个英雄,每个英雄都有自己的特征和和技能,特征即数据属性,技能即方法属性,特

[.net 面向对象程序设计深入](1)UML——在Visual Studio 2013/2015中设计UML类图

[.net 面向对象程序设计深入](1)UML——在Visual Studio 2013/2015中设计UML类图 1.UML简介 Unified Modeling Language (UML)又称统一建模语言或标准建模语言. 简单说就是以图形方式表现模型,根据不同模型进行分类,在UML 2.0中有13种图,以下是他们的主要用途简介: 1.用例图:对系统的使用方式分类. 2.类图:显示类和它们的相互关系. 3.对象图:只显示对象及它们的相互关系. 4.活动图:显示人或对象的活动,其方式类似于流程

sdut 面向对象程序设计上机练习七(类和对象)

面向对象程序设计上机练习七(类和对象) Time Limit: 1000MS Memory limit: 65536K 题目描述 利用类的数据成员和成员函数完成下列操作:输入三个整数,输出它们的最大值. 输入 输入三个整数. 输出 输出3个整数的最大值. 示例输入 2 8 5 示例输出 8 这个就不做详细注释了,初学者也能尝试着看懂. #include <iostream> using namespace std; class shu { private: int a,b,c; public:

sdut 面向对象程序设计上机练习五(简单类和对象)

面向对象程序设计上机练习五(类和对象) Time Limit: 1000MS Memory limit: 65536K 题目描述 定义类Time,Time有3个公用的数据成员hour.min.sec分别表示小时.分.秒. 在主函数main中定义Time类对象t1,在主函数main中输入t1的各数据成员再并输出各数据成员. 输入 输入类对象的3个数据成员hour.min.sec. 输出 输出类对象的3个数据成员hour.min.sec. 示例输入 9 10 11 示例输出 9:10:11 #inc

sdut 面向对象程序设计上机练习六(类和对象)

面向对象程序设计上机练习六(类和对象) Time Limit: 1000MS Memory limit: 65536K 题目描述 用类成员函数完成5个整型数组元素的输入.从小到大排序.排序后数组元素的输出. 输入 输入5个数组元素. 输出 输出5个数组元素从小到大排序后的结果.(最后一个数后面既没有空格也没有换行) 示例输入 8 9 1 5 4 示例输出 1 4 5 8 9 提示 来源 zlh 示例程序 #include <iostream> using namespace std; //定义

[.net 面向对象程序设计进阶] (13) 序列化(Serialization)(五) JSON序列化利器 Newtonsoft.Json 及 通用Json类

[.net 面向对象程序设计进阶] (13) 序列化(Serialization)(五) JSON序列化利器 Newtonsoft.Json 及 通用Json类 本节导读: 关于JSON序列化,不能不了解Json.net(Newtonsoft.Json)这款世界级的开源类库,除了拥有良好的性能之外,功能也是非常强大的. 本节会详细说明这个类库.此外,对于不喜欢使用第三方类库的同学,会整理一个基于微软类库的通用Json类. 读前必备: 本节主要介绍一款第三方类库和一个自己整理封装的类库,说起到封装

[.net 面向对象程序设计进阶] (11) 序列化(Serialization)(三) 通过接口IXmlSerializable实现XML序列化及XML通用类

[.net 面向对象程序设计进阶] (11) 序列化(Serialization)(三) 通过接口IXmlSerializable实现XML序列化及XML通用类 本节导读:本节主要介绍通过序列化接口IXmlSerializable实现XML序列化和反序列化,整理了XML基础操作及序列化的通用类(包括XML及节点的基础读写操作,XML到DataSet\DataTable互转换操作,XML序列化及反序列化通用方法等). 读前必备: A.类和类的实例 [.net 面向对象编程基础]  (9) 类和类的

Java面向对象程序设计--与C++对比说明:系列2(类机制)

1. Java中的包机制(Package): 1.1   Java容许将一系列的类组合到一个叫package的集合中.package机制是一种非常好的管理工作的方式并可以将你自己的工作和系统或第三方提供的代码分开. 一个类(class)可以使用其本身所在包中的任何类和其他包中的任何public类. 注意:只能使用*号来导入一个单独的包中的所有的类.像这种java.*或java.*.*形式的包的导入都是错误的. 例如:有两个包com.a.b和com.a.b.c,那么com.a.b.*导入的类将不包

4.4 类的方法(Methods)- 摘自 《SAP ABAP面向对象程序设计:原则、模式及实践》

<SAP ABAP面向对象程序设计:原则.模式及实践> https://book.douban.com/subject/30317853/ http://www.duokan.com/shop/tbt/book/179473 https://item.jd.com/12423999.html https://e.jd.com/30429611.html 4.4 类的方法(Methods) 类的方法(Methods),指明类具有的功能.数据和服务包成了一个整体,能够有一系列的行为和动作. 类的方