C/C++
jake_wolf
这个作者很懒,什么都没留下…
展开
-
C++对C语言的非面向对象特性扩充(1)
我将分3篇来介绍C++相对于C在非对象特性上的扩充,今天要讲的是C++在注释,输入输出,局部变量说明的扩充,以及const修饰符与C中的#define的比较。 1.C++注释除了包括原有C的块注释/*...*/,还提供了行注释//,另外要注意的是对于注释/*...*/的方式是不能嵌套的,比如/*C++/*C++*/C*/,这是不允许的。但是嵌套注释//是可以的。 2.我想大家对翻译 2013-11-16 21:28:35 · 822 阅读 · 0 评论 -
C++类中定义的类
类中定义类主要是为了数据封装,要访问B类,可以使用A::B来用。class A{public: void test1(){cout<<"test1"<<test->test2()<<endl;} class B { public: char* test2(){return "_test2";} protected: private: }; B *test;};转载 2015-11-12 22:59:12 · 5000 阅读 · 2 评论 -
关于宏定义中#和##符号的使用和宏定义展开问题
有一道经典的C语言问题,关于宏定义中#和##符号的使用和宏定义展开问题程序如下:#include <stdio.h>#define f(a,b) a##b#define g(a) #a#define h(a) g(a)int main(){ printf("%s\n", h(f(1,2))); printf("%s\n", g(f(1,2)));转载 2015-11-12 23:24:11 · 1169 阅读 · 0 评论 -
C++template中typename 和class的区别
由于历史原因,以前是用class,后来C++ Standard 出现后,引入了typename, 实际上可以说没有区别。按 C++ 标准来说,template <typename T> 用于基础数据类型,typename 指类型名,T 可以取 char int double 等。template<class T> 用于类,T 可以取任何类。但是这里有一个问题,结构体应该用 typename 还是 c转载 2015-11-12 22:49:25 · 597 阅读 · 0 评论 -
C++ 结构体初始化方法
C++结构体初始化有以下几种方法:使用构造函数 在C++中,struct可以当做类(class)来使用,同样支持成员函数,构造函数,析构函数。所以可以写对应的构造函数,实现自由初始化。定义时,按照成员变量位置,写初始化列表。 如struct test中有成员int a, char b, 和float c,那么初始化一个变量可以写作struct test t1 = {100, 'A', 1.转载 2015-11-12 23:15:33 · 7139 阅读 · 0 评论 -
虚函数、纯虚函数、普通函数的区别
1.虚函数(impure virtual) C++的虚函数主要作用是“运行时多态”,父类中提供虚函数的实现,为子类提供默认的函数实现。子类不一定要重写虚函数,子类可以重写父类的虚函数实现子类的特殊化。如下就是一个父类中的虚函数:class A{public: virtual void out2(string s) { cout<<"A(out2):"<<s<<e转载 2015-11-12 23:34:32 · 994 阅读 · 0 评论 -
结构体和类的区别
1.C的结构体和C++结构体的区别C的结构体内不允许有函数存在,C++允许有内部成员函数,且允许该函数是虚函数。所以C的结构体是没有构造函数、析构函数、和this指针的。C的结构体对内部成员变量的访问权限只能是public,而C++允许public,protected,private三种。C语言的结构体是不可以继承的,C++的结构体是可以从其他的结构体或者类继承过来的。以上都是表面的区别,实际区别就转载 2015-11-13 20:53:53 · 319 阅读 · 0 评论 -
关于C++中子类调用父类方法的一个问题
在写代码时遇到了以下类似情况:#include <iostream>#include <string>using namespace std;class A {public: void func1(string prefix) { cout << prefix << "A::func1" << endl; } void func2(string prefi转载 2015-11-13 21:11:34 · 3045 阅读 · 0 评论 -
成员函数后面加const,没有const,以及使用的区别
函数后面加const 编译器会自动给每一个函数加一个this指针。在一个类的函数后面加上const后,就表明这个函数是不能改变类的成员变量的(加了mutable修饰的除外,后面有讲)。实际上,也就是对这个this指针加上了const修饰。#include <iostream> using namespace std; class CTest { public: void s转载 2015-11-13 21:33:40 · 782 阅读 · 0 评论 -
C++ 构造过程和析构过程
1、C++构造和析构的过程,类似于穿衣脱衣的过程。穿衣是:先穿内衣,再穿外套。脱衣是:先脱外套,再脱内衣。C++构造过程:首先调用父类构造方法,再调用子类构造方法。C++析构过程:首先调用子类析构方法,再调用父类析构方法。2、子类不能继承父类的构造方法和析构方法,除此之外,其他的成员都能继承,包括父类的private成员,只不过子类不能访问private成员。3、思考一下,为什么子类不能继承父类的构转载 2015-11-13 21:41:01 · 1716 阅读 · 0 评论 -
C++中this指针的用法详解
1. this指针的用处: 一个对象的this指针并不是对象本身的一部分,不会影响sizeof(对象)的结果。this作用域是在类内部,当在类的非静态成员函数中访问类的非静态成员的时候,编译器会自动将对象本身的地址作为一个隐含参数传递给函数。也就是说,即使你没有写上this指针,编译器在编译的时候也是加上this的,它作为非静态成员函数的隐含形参,对各成员的访问均通过this进行。例如,调用d转载 2015-11-13 21:03:49 · 377 阅读 · 0 评论 -
#ifdef和#if defined之间的区别
#ifdef和#if defined之间的区别 两者的用法基本上一样,不过后者的应用范围更大,可以支持多个预编译变量的检查:#if (!defined(_DEBUG) && defined(USE_MYLIB))..........#endif这种情况用前一种方式就只能写一个嵌套的条件判断:#ifndef _DEBUG#ifdef USE_MYLIB................#en转载 2015-11-13 21:38:54 · 786 阅读 · 0 评论 -
C++类的多继承
派生类都只有一个基类,称为单继承。除此之外,C++也支持多继承,即一个派生类可以有两个或多个基类。 多继承容易让代码逻辑复杂、思路混乱,一直备受争议,中小型项目中较少使用,后来的 Java、C#、PHP 等干脆取消了多继承。想快速学习C++的读者可以不必细读。 多继承的语法也很简单,将多个基类用逗号隔开即可。例如已声明了类A、类B和类C,那么可以这样来声明派生类D:class D: public转载 2015-11-13 21:18:02 · 433 阅读 · 0 评论 -
C++之友元类
什么是友元类当一个类B成为了另外一个类A的“朋友”时,那么类A的私有和保护的数据成员就可以被类B访问。我们就把类B叫做类A的友元。友元类能做什么友元类可以通过自己的方法来访问把它当做朋友的那个类的所有成员。但是我们应该注意的是,我们把类B设置成了类A的友元类,但是这并不会是类A成为类B的友元。说白了就是:甲愿意把甲的秘密告诉乙,但是乙不见得愿意把乙自己的秘密告诉甲。友元类的声明方法和其用法声明友元类转载 2015-11-12 22:35:09 · 558 阅读 · 0 评论 -
关于数组长度不需要编译时确定
一直深信,数组长度必须是一个编译时可确定的常数,最近才发现自己真的是out了,自己真的是老了。 C99标准已经支持变长数组,换言之,数组的长度可以在运行时确定,没有任何问题。但是有个问题,就是数组只能够声明,不能初始化,因为编译器并不知道数组的长度,无法初始化。 请看下面的例子: 第一个例子,表明数组长度可以直到运行时才确定。 第二个例子表明转载 2014-01-02 22:23:08 · 2655 阅读 · 0 评论 -
free store 和 heap
free store (自由存储区)和 heap (堆),在C/C++中经常会遇到。他们是否有区别呢?偶最早发现这两个概念性问题是在《Exceptional C++》一书中。其中提到C++中使用new分配所得的内存是分配在 freestore 上,而C 风格的内存分配 malloc 分配所得的内存是在 heap 上。额。这个有什么区别呢?通过在 Google 的搜索转载 2013-10-26 16:08:02 · 618 阅读 · 0 评论 -
C++运算符重载补充之不同数据间的类型转换
我们在使用重载的运算符时,往往需要在自定义数据类型和系统预定义的数据类型之间进行转换,或者需要在不同的自定义数据类型之间进行转换。今天就来讲讲C++中数据类型的转换。 1.对于系统的预定义基本类型数据,C++提供了两种类型转换方式:隐式类型转换和显式类型转换。int a=5,sum;double b=5.55; sum=a+b;//-------(1) std:转载 2013-11-14 13:33:55 · 773 阅读 · 0 评论 -
C++之模板
有以下这样3个求加法的函数: int Add(int x,int y){return x+y;}double Add(double x,double y){return x+y;}long Add(long x,long y){return x+y;}它们拥有同一个函数名,相同的函数体,却因为参数类型和返回值类型不一样,所以是3个完全不同的函数。即使它们是转载 2013-11-14 14:24:06 · 387 阅读 · 0 评论 -
c++ try_catch throw
抛出异常(也称为抛弃异常)即检测是否产生异常,在C++中,其采用throw语句来实现,如果检测到产生异常,则抛出异常。该语句的格式为:throw 表达式; 如果在try语句块的程序段中(包括在其中调用的函数)发现了异常,且抛弃了该异常,则这个异常就可以被try语句块后的某个catch语句所捕获并处理,捕获和处理的条件是被抛弃的异常的类型与catch语句的异常类型相匹配。由于C++使用转载 2013-10-26 17:24:25 · 713 阅读 · 0 评论 -
C++ pair的用法
1 pair的应用pair是将2个数据组合成一个数据,当需要这样的需求时就可以使用pair,如stl中的map就是将key和value放在一起来保存。另一个应用是,当一个函数需要返回2个数据的时候,可以选择pair。 pair的实现是一个结构体,主要的两个成员变量是first second 因为是使用struct不是class,所以可以直接使用pair的成员变量。2 make_pa转载 2013-09-19 21:47:09 · 506 阅读 · 0 评论 -
C++类构造函数初始化列表
构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。例如:class CExample {public: int a; float b; //构造函数初始化列表 CExample(): a(0),b(8.8) {} //构造函数内部赋值 CExample() {转载 2013-11-14 12:04:45 · 664 阅读 · 0 评论 -
public,private,protected关键字
1:private, public, protected 成员函数private:只能由1.该类中的函数、2.其友元函数访问。不能被任何其他访问,该类的对象也不能访问。protected:可以被1.该类中的函数、2.子类的函数、以及3.其友元函数访问。但不能被该类的对象访问。public:可以被1.该类中的函数、2.子类的函数、3.其友元函数访问,也可以由4.该类的转载 2013-11-12 18:45:08 · 786 阅读 · 0 评论 -
explicit构造函数
按照默认规定,只有一个参数的构造函数也定义了一个隐式转换,将该构造函数对应数据类型的数据转换为该类对象,如下面所示:class String {String ( const char* p ); // 用C风格的字符串p作为初始化值//…}String s1 = “hello”; //OK 隐式转换,等价于String s1 = String(“hello”转载 2013-11-12 18:36:32 · 593 阅读 · 0 评论 -
为什么基类的析构函数是虚函数?
1.为什么基类的析构函数是虚函数? 在实现多态时,当用基类操作派生类,在析构时防止只析构基类而不析构派生类的状况发生。a.第一段代码#includeusing namespace std;class ClxBase{public: ClxBase() {}; ~ClxBase() {cout << "Output from the destr转载 2013-11-12 17:05:52 · 589 阅读 · 0 评论 -
public private 和protected 继承
public private 和protected 继承 在C++中继承主要有三种关系:public、protected和private。这三种继承关系中public继承是最为常用的一种继承关系,private继承是最少见的继承关系。1. public从语义角度上来说,public继承是一种接口继承,根据面向对象中的关系而言就是,派生类可以代替基类完成基类接口所声明的行为,也就转载 2013-10-13 11:52:12 · 542 阅读 · 0 评论 -
C++之运算符重载(2)
上一节主要讲解了C++里运算符重载函数,在看了单目运算符(++)重载的示例后,也许有些朋友会问这样的问题。++自增运算符在C或C++中既可以放在操作数之前,也可以放在操作数之后,但是前置和后置的作用又是完全不同的(q前置运算符:先加1,再赋值;后置运算符:先赋值,再加1)。那么要怎么重载它们,才可以有效的区分开来呢?今天我就来说说C++中是怎么处理前置运算符和后置运算符的重载的。以及介绍一下插入运转载 2013-11-14 13:02:36 · 648 阅读 · 0 评论 -
C++之运算符重载(1)
在前一节中曾提到过,C++中运行时的多态性主要是通过虚函数来实现的,而编译时的多态性是由函数重载和运算符重载来实现的。这一系列我将主要讲解C++中有关运算符重载方面的内容。在每一个系列讲解之前,都会有它的一些基础知识需要我们去理解。而运算符重载的基础就是运算符重载函数。所以今天主要讲的是运算符重载函数。 1.运算符重载是对已有的运算符赋予多重含义,使同一个运算符作用域不同类型的数据导致不转载 2013-11-12 19:38:32 · 584 阅读 · 0 评论 -
C++类中的枚举类型
有时我们希望某些常量只在类中有效。 由于#define 定义的宏常量是全局的,不能达到目的,于是想当然地觉得应该用 const 修饰数据成员来实现。const 数据成员的确是存在的,但其含义却不是我们所期望的。const 数据成员只在某个对象生存期内是常量,而对于整个类而言却是可变的,因为类可以创建多个对象,不同的对象其 const 数据成员的值可以不同。 不能在类声明中初始化 con转载 2015-11-24 23:12:20 · 1449 阅读 · 0 评论