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中的面向对象编程,这里不做过多过细的讨论,主要做提纲挈领的描述,帮助自己抓做重点. 本随笔分为两部分: 一.面向对象编程 二.面向对象编程详细描述 ------------ ...
随机推荐
- JDBC体会
1.把mysql-connector XXXX版本导入buildpath 2.通过DriverManager 的getConnection 方法获得一个Connnection引用,方法的参数是 url ...
- POJ 1185 炮兵阵地(经典的状态压缩DP)
题意:中文题. 思路,经典的状态压缩题目. 由于列长比较小,我们可以以行为阶段用状态压缩来做. 由于攻击只占两个格,这样从行的角度看,第i行的炮兵只与前i-1和前i-2行有关系.这样如果用j,k,l分 ...
- weblogic服务器的简单使用(一)
一.前言 现在的公司开发的项目基于的平台是weblogic8.1.5,虽然版本是旧了点,但是用到的功能还是很多的,如JNDI.t3协议.EJB2.0.线程池.连接池.Ant部署.java远程调试. 发 ...
- javascript笔记3-面向对象的程序设计-创建对象
javascript的对象:无序属性的集合,而每个属性可以包含基本值.对象或者函数.举例: var person = new Object(); person.name = "Nichola ...
- ios中摄像头/相册获取图片,压缩图片,上传服务器方法总结
相册 iphone的相册包含摄像头胶卷+用户计算机同步的部分照片.用户可以通过UIImagePickerController类提供的交互对话框来从相册中选择图像.但是,注意:相册中的图片机器路径无法直 ...
- 查询某个表或者所有表的字段说明 SQLServer
查询某个表或者所有表的字段说明SELECT [Table Name] = OBJECT_NAME(c.object_id), [Column Name] = c.name, [Des ...
- python3爬虫初探(三)之正则表达式
前面已经写了如何获取网页源码,那么接下来就是该解析网页并提取需要的数据了.这里简单写一下正则表达的用法. 首先,找个要抓取图片的网站,获取源码. import requests import re # ...
- JQuery源码分析(三)
jQuery中ready与load事件 jQuery有3种针对文档加载的方法 $(document).ready(function() { // ...代码... }) //document read ...
- 使用RBL拦截垃圾邮件
1. sbl-xbl.spamhaus.org 2 bl.spamcop.net 3 zen.spamhaus.org
- HDU 4576
http://acm.hdu.edu.cn/showproblem.php?pid=4576 题意:给一个1-n的环,m次操作,每次操作顺时针或逆时针走w步,求最后落在[l,r]区间的概率 dp[i] ...