C++面向对象要点
先说说面向对象思想的一个总体认识
对象通常会有行为,这些行为是靠信息支撑,这些信息包括外部信息和内部信息,对象行为会维护其中的一部分信息
因此对象可以看成是这样一种实体,它获取信息,然后决定自己的行为方式,并主动对全部或部分信息进行维护。此外
对象的定义可以是递归的,即行为可以涉及到若干个更小功能的对象,信息也可以涉及多个更小功能的对象
1.静态数据成员必须初始化
2.只有静态常量整数型成员才可以在类中初始化,即cont static int a;才可以
3.虚函数 virtual void fun(){}
4.纯虚函数 virtual void fun(){}=0
5.虚基类 class A:virtual public B{}
5.常成员函数 void fun(){} const
不会改变对象的数据成员,总之,它是获取对象的状态而不能改变对象的状态
const代表的是只读特性 static指的是生存周期
6.常对象 const Student stu;Or Student const stu;
7.友元函数 class A{friend void fun(){}} void fun(){}
8.友元类 class A{friend class B};B可以方位A的私有成员和保护成员。
9.protected 受保护成员 所有后代类(不论什么层级)都可以访问。
10.虚函数表
11.复制构造函数 A(const &A obj){}//const意即仅仅是复制,不需要改变被复制对象的状态
用途:1)返回值是一个对象 2)对象作为参数 3)初始化另一个对象
12.构造函数初始化列表
四种情况必须用,1.object member 2.const data member3. Reference type member4.baseclass contructor
CClassA::CClassA(): x(0), y(1){}
13.派生类构造函数
须以参数列表的形式初始化的是对象成员,基类,派生类可列表可函数内初始化,基类的构造函数不能在派生类中重载
14.对象的数据成员和函数成员是分开存放的,并且即使程序中没有建立类的对象,但该类的函数还是会存在于程序中
15.typeid
通常情况下,类型名称的是在编译时就完成了,涉及到多态,或者说有虚函数存在的情况下,并不在编译时确定类型名称,而是
引入虚函数表,这时类的指针不指向对象的第一个数据成员,而是指向虚函数表,相关的类型名称作为该表的一条记录出现
这条记录指向了类名称的字符串,下面是一个例子:
class B
{
virtual fun(){cout<<"This is a base class"<<endl;}
};
class C:public B
{
void fun(){cout<<"This is a derived class"<<endl;}
void fun2(){}
};
//main function
C c;
B *p;
p=&c;
cout<<typeid(p).name()<<endl;//output:class B *
cout<<typeid(*p).name()<<Endl;//output:class C
p->fun()//output:This is a derived class
p->fun2()//error:can't operate a class C's member function through a type B pointer
16.关于virtual function
只要是virtual function,一定会通过虚函数表调用
先说一下虚函数表的内存结构,对于一个有虚函数表的派生类对象的内存起始地址,首先是存放了其虚函数表的地址,然后是数据成员,如果派生类继承自多个基类,那么按照继承的顺序排列基类的(虚函数表地址+数据成员),最后存放派生类的数据成员,新增加的虚函数会放在第一个虚函数表后面。再说一下C++中关于类对象的类型转换机制:
static_cast:
会改变内存结构,自下而上的转换是安全的,自上而下的转换是不安全的,因为这种转换不做安全检查。
dynamic_cast:
会改变内存结构,这是一种类型安全的转换,除了虚函数表,C++编译器还保留了类的类型信息(位于虚函数表向上偏移若干字节),转换时会检查这些类型信息,至于内存中怎么存放这些类型信息以及怎么做检查,这些不同编译器会有不同的实现。
reinterept_cast:
不会改变内存结构,就像他的字面意思,只进行重新解释。
下面的转换都是static_cast
class ParentClass { public : virtual void foo() {/*...*/}; };
class DerivedClass : public ParentClass { public : virtual void foo() {/*...*/};}; DerivedClass derived;
ParentClass parent = (ParentClass)derived;
ParentClass* pObj = &parent;
pObj->foo();
class base
{
public:
virtual void fun()
{printf("bas");} };
class derive:public base
{public:
void fun()
{printf("child");} };
class CC:public derive
{
public:void fun()
{printf("another");}
};
base *p;
CC c;
p=&c;
p->fun().//output another
参考:http://www.cnblogs.com/zhyg6516/archive/2011/03/07/1971898.html
此外static dynamic之所以这样命名也符合这两种转换的性质,static是在编译时期就确定了的,并且已经转换好了,但是他不保证安全,需要开发者自己保证安全,dynamic是运行时进行的转换,通过获取类型的信息,来决定如何转换,转换不成就返回null,因此是安全的,所谓的安全就是不会试图去访问意料之外的内存。
c++提供<typeinfo.h>和typeid来动态获取对象的类型信息
17.在线编译器codepad.org http://ideone.com/ cpp.sh
18.关于<< >>为什么不能重载为成员函数,这里指的是istream ostream之外的类需要重载<<和>>的时候是不适合将其重载为成员函数的,因为如果重载为成员函数,函数的默认的第一个参数是this指针,而第一个参数又对应着运算符的左操作数,在使用的时候就是CObj>>cout,这样可以达成对CObj的个性化输出,但是无法进行串连式的流操作,需要注意的是,这里所说的不能重载为成员函数是对于标准输出输入流之外的类而言的,事实上istream 和 ostream 也是将<<>>重载为成员函数的。
19.函数默认参数,规定有默认值的参数全部放在列表右边,如:int fun(int a=0,int b,int c)不合法,而int fun(int b,int c,int a=0)合法。
20.cplusplus网站上对于类的基类只列出了从中继承的function,数据成员并没有列出来,这一点要注意,但是类自身的数据成员是在左侧列出来的。
21.c++嵌套类的使用是必须要带作用域的,比如class A{class B{};};使用B类型时一定要用A::B才可以。
22.类模版的偏特化,其实叫做类模版的重载也比较合适
23.右值引用
vector<int> getv()
{
vector<int> v;
return v;
}
int main()
{
vector<int> tmp=getv();
return 0;
}
上面的程序按理说最多发生二次对象的拷贝
1.getv返回的时候发生一次(虽然这一次可以被编译器优化掉)
2.使用=号赋值的时候发生一次(这一次是避免不了的)
另外,如果你在一个类中只提供了move constructor ,但是在=号赋值,或者直接创建对象的时候并没有匹配到move constructor 这时候编译器会自动生成一个复制构造函数
在实践了很多右值引用后,还有返回右值引用的函数,我感觉右值引用最关键的一个功能就是阻止拷贝(复制)的发生。
24.c++数组的引用
void foo(T(&arr)[N])
{
bar(std::begin(arr), std::end(arr));
}
其实我早就说过,引用的引入实际上就是为了掩蔽c++中对指针的操作,使得c++更加语义化,更加natural,此例中函数传递数组的运用就是一个很好的例子
C++面向对象要点的更多相关文章
- php 面向对象要点汇总
//类和对象//对象:一切东西都可以看做对象,对象是类的实例化.//类:类是对象的抽象,用来描述众多对象共有的特征. //定义类 class//成员变量 和 成员方法//访问修饰符 public共有的 ...
- Java面向对象要点
面向对象: 一.基本概念 类与对象的基本概念: 1.void类型是不需要返回值的,其他类型全部都需要返回值. public void tell(){ ...
- 面向对象要点(this关键字)
package day07; public class ThisKeywords { private String name; private void Foo(String name) { this ...
- javascript的面向对象编程
面象对象编程技术的核心理念:封装.继承.多态:在一些主流的高级编程语言中,比如:C#,VB.NET,JAVA,PHP等都是很容易实现的,而如果要在javascript中实现面象对象编程,可就不那么直接 ...
- javascript必知必会:面象对象编程
面象对象编程技术的核心理念:封装.继承.多态:在一些主流的高级编程语言中,比如:C#,VB.NET,JAVA,PHP等都是很容易实现的,而如果要在javascript中实现面象对象编程,可就不那么直接 ...
- PHP面向对象编程知识要点
1.基本概念 1.1.面向对象的阶段概念 OOA:面向对象分析 OOD:面向对象设计 OOP:面向对象编程 1.2.类的概念 面向对象中的类,实质上就是现实世界中一类有着相似属性事物抽象的概括,像鸟类 ...
- JavaScript的语法要点 4 - 面向对象的基础
在传统的面向对象语言如C++.C#.Java中有类.对象.继承等概念.在JavaScript中又如何表示呢?JavaScript中没有class关键字,JavaScript中的类.对象.继承的概念是通 ...
- javascript的面向对象思想知识要点
获取数据类型 typeof undefined:访问某个不存在的或未经赋值的变量时就会得到一个 undefined,用typeof 获取类型,得到的也是undefined;null:它不能通过java ...
- Delphi_09_Delphi_Object_Pascal_面向对象编程
今天这里讨论一下Delphi中的面向对象编程,这里不做过多过细的讨论,主要做提纲挈领的描述,帮助自己抓做重点. 本随笔分为两部分: 一.面向对象编程 二.面向对象编程详细描述 ------------ ...
随机推荐
- ansible quick start
1. ansible默认开启ControlPersist,也就是持续化ssh的socket连接,以跳过每次task都需要进行主机认证. 2. 但是centos的openssh版本太老了,不支持Cont ...
- mybatis多对一关联的两种方式
第一个种是Address找到自己的user_id,扔给User,让User自己去再查一次,即使在有缓存的前提下,每遇到一个新的user_id,就会查一次,对比hibernate的话,相当于多对一eag ...
- dotTracePerormance 工具
今天凌晨 阿根廷对瑞士比赛已经过去,比分是1:0 阿根廷获胜:虽说我是伪球迷,但是也挺希望梅西进入决赛.昨晚也压了下90分之内 0:0 ,结果胜出:另一场压的是美国对比利时,也是压平,就这样二串 ...
- java应用程序和虚拟机实例之间的关系
每一个java程序都会产生一个java虚拟机的实例.并不是说一个物理机上,运行多个java应用程序就只有一个java虚拟机实例,多少个java应用程序就有多少个java虚拟机实例.
- druid简介
Druid首先是一个数据库连接池,但它不仅仅是一个数据库连接池,它还包含一个ProxyDriver,一系列内置的JDBC组件库,一个SQL Parser. 支持的数据库 Druid支持所有JDBC兼容 ...
- hadoop 中对Vlong 和 Vint的压缩方法
hadoop 中对java的基本类型进行了writeable的封装,并且所有这些writeable都是继承自WritableComparable的,都是可比较的:并且,它们都有对应的get() 和 s ...
- codeforces #round363 div2.C-Vacations (DP)
题目链接:http://codeforces.com/contest/699/problem/C dp[i][j]表示第i天做事情j所得到最小的假期,j=0,1,2. #include<bits ...
- aspx页面图片用作html中img的url
背景:如果无法直接访问保存图片的服务器,我们可以先制作一个aspx页面用来接受服务器发送过来的图片,然后html页面请求aspx页面.对图片服务器起一定的缓冲保护作用,预防对黑客攻击造成危害. 注意: ...
- HDU 5025
http://acm.hdu.edu.cn/showproblem.php?pid=5025 蛇最多只有五条,状态压缩一下,vis增加两维,表示取得钥匙的状态和蛇的状态,然后一个优先队列的bfs即可解 ...
- LeetCode Path Sum II (DFS)
题意: 给一棵二叉树,每个叶子到根的路径之和为sum的,将所有可能的路径装进vector返回. 思路: 节点的值可能为负的.这样子就必须到了叶节点才能判断,而不能中途进行剪枝. /** * Defin ...