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中的面向对象编程,这里不做过多过细的讨论,主要做提纲挈领的描述,帮助自己抓做重点. 本随笔分为两部分: 一.面向对象编程 二.面向对象编程详细描述 ------------ ...
随机推荐
- java基础-006
37.JDBC JDBC是允许用户在不同数据库之间做选择的一个抽象层.JDBC允许开发者用JAVA写数据库引用程序,而不需要关心底层特定数据库的细节. 38.驱动(Driver) 在JDBC中的角色 ...
- 等价表达式(noip2005)
3.等价表达式 [问题描述] 兵兵班的同学都喜欢数学这一科目,中秋聚会这天,数学课代表给大家出了个有关代数表达式的选择题.这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也 ...
- 理解NSTextContainer
Apple的Doc对这个类的描述是这样的: The NSTextContainer class defines a region where text is laid out. An NSLayout ...
- Ubuntu 14.10 下进程实时IO监控iotop命令详解
介绍 Linux下的IO统计工具如iostat, nmon等大多数是只能统计到per设备的读写情况, 如果你想知道每个进程是如何使用IO的就比较麻烦. iotop 是一个用来监视磁盘 I/O 使用状况 ...
- NSHTTPCookie类详解
继承自 NSObject的 符合 NSObject的(NSObject的) 框架 /系统/资源库/框架/ Foundation.framework 可用性 安装使用Safari 1.0在Mac OS ...
- Candy Distribution_找规律
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6012 Accepted: 3341 Description N chi ...
- GIT之二 基础篇(2)
远程仓库的使用 要参与任何一个 Git 项目的协作,必须要了解该如何管理远程仓库.远程仓库是指托管在网络上的项目仓库,可能会有好多个,其中有些你只能读,另外有些可以写.同他人协作开发某个项目时,需要管 ...
- HDU 3335
http://acm.hdu.edu.cn/showproblem.php?pid=3335 题意:在给出的n个数中找出一个集合,使得其中的数互不整除,求该集合最大的元素数量 首先要对输入的数去重,输 ...
- dede文章摘要字数的设置方法
本文转自:http://blog.csdn.net/yxwmzouzou/article/details/17491991 在织梦系统中(针对5.7版本),文章摘要(可以通过以下四种相关标签调用)被设 ...
- 帝国cms相关调用
Loop用法:[!--temp.header--] [e:loop={6,6,0,1}] <!--标题连接/标题--> <a href="<?=$bqsr[title ...