Cocos2d-x 系列三之C++语言

1.面向对象
<1>直接定义类


class People {
public:
void sayHello() {
printf("hello c oop \n");
}
};


    People * p = new People();
p->sayHello();

<2>使用头文件定义

Ml.h


#ifndef ML_H_
#define ML_H_

namespace cjyn { // 命名空间

class Ml {
public:
void sayHello();
};
}
#endif /* ML_H_ */

Ml.cpp


#include "Ml.h"
#include <iostream>
#include <stdio.h>
namespace cjyn {

void Ml::sayHello() { // 返回类型 类名::方法名
printf("hello cpp");
}

}

main.cpp 调用


#include <iostream>
#include "Ml.h"
#include <stdio.h>
using namespace cjyn;

int main(int argc, const char* argv[]) {
cjyn::Ml *ml = new cjyn::Ml();
ml->sayHello();
delete ml; // 释放对象,如同C中的free
}

补充:如果没有引入using namespace
cyjn,则在申明类的时候需要使用(命名空间::类名)的方式,如果引入了命名空间,则上面的申明可以直接使用类名而不需要使用命名空间;

2.类的继承(People->Man)

People.cpp


#include "People.h"
#include <iostream>
#include <stdio.h>

void People::sayHello() {
printf("hello cpp");
}

int People::getAge() {
return this->age;
}

People::People(int age) {
this->age = age;
}
People::People() {
this->age = 12;
}

People.h


#ifndef ML_H_
#define ML_H_

class People {
private:
int age;
public:
People();
People(int age);
void sayHello();
void setAge();
int getAge();
};

#endif /* ML_H_ */

子类Man

Man.cpp


#include "Man.h"

Man.h


#ifndef MAN_H_
#define MAN_H_
#include "People.h"

class Man: public People { // public 表示从父类继承下来的成员变量是public的
public:
};
#endif /* MAN_H_ */

main.cpp


int main(int argc, const char* argv[]) {
Man *m = new Man();
m->sayHello(); //hello cpp
delete m;
}

3.引用父类方法

<1>.构造方法

Man.h


#ifndef MAN_H_
#define MAN_H_
#include "People.h"

class Man: public People { // public 表示从父类继承下来的成员变量是public的
public:
Man(int age);
void sayHello();
};
#endif /* MAN_H_ */

Man.cpp


Man::Man(int age) : People(age) { // 想要执行父类的构造方法只需要在子类构造方法之后加冒号并且调用父类构造方法即可
}

<2>.其他方法调用

Man.cpp


Man::Man(int age) : People(age) {
People::sayHello(); // @1
}

void Man::sayHello() {
printf("man say hello cpp\n");
}

Man.h


class Man: public People { // public 表示从父类继承下来的成员变量是public的
public:
Man(int age);
void sayHello();
};
#endif /* MAN_H_ */

main.cpp


int main(int argc, const char* argv[]) {
Man *m = new Man(34);
printf("age %d \n", m->getAge());
m->sayHello(); // 调用man的sayHello
m->People::sayHello(); // 调用People的sayHello @2
delete m;
}

父类普通方法的调用之需要在方法名前加(类名::方法名),有两种调用方式@1,@2;

4.面向对象特点

<1>.虚函数、纯虚函数、纯虚类


class People {
private:
int age;
public:
People();
People(int age);
// 虚函数:定义为虚函数之后就可以在运行的时候动态加载相应的方法(相当于java中多态);
virtual void sayHello();
// 纯虚函数,相当于java中的抽象方法;对应的类就是抽象类
virtual void eat()=0;
void setAge();
int getAge();
};
#endif /* ML_H_ */

纯虚类就是类中所有方法都是纯虚函数,相当于java中的接口;
虚函数和纯虚函数分别由子类去重写(可重写可不重写)和实现(子类必须进行实现);

Man.h


class Man: public People {
public:
Man(int age);
virtual void sayHello();
virtual void eat();
};
#endif /* MAN_H_ */

Man.cpp


Man::Man(int age) : People(age) { // 调用父类构造方法
}

void Man::sayHello() {
printf("man say hello cpp\n");
}

void Man::eat(){
printf("man eat\n");
}

5.操作符重载


class Point {
private:
int x, y;
public:
Point(int x, int y) {
this->x = x;
this->y = y;
}

void add(Point p) {
this->x += p.x;
this->y += p.y;
}

void operator +=(Point p) {
add(p);
}

int getX() {
return this->x;
}
int getY() {
return this->y;
}
};

实例:


int main(int argc, const char* argv[]) {
Point p(10, 10);
std::cout << p.getX() << "\n";
p += Point(12, 12);
std::cout << p.getX() << "\n";

Point *pp = new Point(5, 5);
(*pp) += Point(4, 4);
std::cout << pp->getX() << "\n";
}

上述代码输出结果为:10,22,9;

<2>.操作符重载之伪函数

伪函数就是把一个类当作一个方法来调用,下面直接看例子


class Point {
public:
void operator ()() {
std::cout << "hello point" << "\n";
}
};

使用(这种方式的有点在于比如把类当作一个参数传递)


int main(int argc, const char* argv[]) {
Point p;
p(); // 输出hello point
}

6.函数指针

C++中函数指针和C语言中函数指针其实比较类似,下面是C语言中的两种定义方法

  • void (*Pointer)();

  • typedef void (*Pointer)();

接着来看C++中函数指针的定义

  • @1


  • class Object
    {
    public:
    void (Object::*sayHi)();
    };


  • @2


  • class Object;
    typedef void (Object::*SayHi)();

    class Object
    {
    public:
    SayHi sayHi;
    };


通过上面的例子不难看出,都是返回类型+(指针名称定义)+(参数)
,不过在C++中,需要定义函数指针所在的类,在上面即是限定指针为Object的成员或者Object子类的成员;

下面看一个例子:编写一个类继承自Object,并且给sayHi指针赋值;


class Hello : public Object
{
public:
Hello(){
//sayHi = (void(Object::*)())(&Hello::helloSayHi); 将Hello本身的helloSayHi方法赋予sayHi;使用@1方式定义指针
//sayHi = (SayHi)(&Hello::helloSayHi); 将Hello的helloSzyHi方法赋予sayHi,使用@2方式定义指针

//(this->*sayHi)(); // 执行sayHi指针;
}
void helloSayHi(){
printf("hello say hi\n");
}
};

再来看一个例子(延迟执行):


class Object;
typedef void (Object::*CallaterHandler)(); // 定义一个指针,该指针所属类为Object类;

#define CH(fp) (CallaterHandler)(&fp) // 取fp的地址,强制转换为CallaterHandler;

void threadFunc(Object *obj,CallaterHandler handler,int delay){
// _Thrd_sleep(d); // thread sleep
(obj->*handler)(); // 执行handler指针
}

void callater(Object *obj,CallaterHandler handler,int delay){
std::thread t(threadFunc,obj,handler,delay);
t.join();
}

class Object
{};

class Hello :
public Object
{
public:
Hello(){
//callater(this,(CallaterHandler)(&Hello::helloSayHi),3);
callater(this,CH(Hello::helloSayHi),3);
}
void helloSayHi(){
printf("hello say hi\n");
}
};

7.引用

先来看一个例子


class PP {
public:
PP(int x) {
this->x = x;
}
void add(PP p) {
this->x += p.getX();
}
int getX() {
return this->x;
}
private:
int x;
};

上面的add方法传入一个PP对象,在执行相加方法时,会对传入的对象进行内存的拷贝,事实上这样的效率不高,为了防止内存的拷贝,可以把add方法更改为
add(PP &p)  //
&表示取地址
当然,这样的实现完全可以直接通过指针来代替;

8.有元类

在C++中,默认没家修饰符的字段为private,但是有时候需要把特定的字段公开给某一个类,这时候就需要用到有元类;


class A {
friend class B; // 通过这样定义,就可以在B类中访问到num
private:
int num;
public:
A() {
num = 10;
}
};

class B {
public:
B() {
A a;
printf("%d", a.num);
}
};

9.集合|容器


int main(int argc, const char* argv[]) {
std::list<std::string> l; // 需要导入list
l.push_back("hello");
l.push_back("spring");
std::list<std::string>::iterator it = l.begin();
for (; it != l.end(); it++) {
std::cout << *it << "\n";
}

map<string, string> m; // 需要导入map
m.insert(pair<string, string>("key1", "value1"));
m.insert(pair<string, string>("key2", "value2")); //
m["key1"] = "value1+"; //
cout << m.at("key1");

return 0;
}

上面的代码输出结果为:hello spring value1+

10.字符串


#include <iostream>
#include <string>
#include <sstream>

using namespace std;

int main(int argc, const char* argv[]) {
string s;
s += "hello ";
s += "string";
cout << s << "\n";

stringstream ss;
ss << "hello";
ss << 23;
ss << "spring" << 25;
cout << ss.str()<<"\n";
return 0;
}

11.文件操作


#include <iostream>
#include <string>
#include <sstream>
#include <fstream>

using namespace std;

int main(int argc, const char* argv[]) {
// ofstream of("data.txt");
// of << "hello cpp \n";
// of.close();

ifstream inf("data.txt");

char c;
inf >> c;
cout << c << "\n"; // 读取第一个字符

stringbuf sb;
inf >> &sb;
cout << sb.str() << "\n"; // 读取全部字符
return 0;
}

Cocos2d-x 系列三之C++语言

时间: 2024-08-03 17:25:55

Cocos2d-x 系列三之C++语言的相关文章

使用 PySide2 开发 Maya 插件系列三:qt语言国际化(internationalization)

使用 PySide2 开发 Maya 插件系列三:qt语言国际化(internationalization) 前言: 这是 qt for python 的语言国际化,基于 UI 的,python 也有自身的语言国际化,两者是不同的. 先来看最终效果: 前期准备: 这次创建一个 main window 在 menu bar 加一个 language 的 menu: 我们还要对 action 进行一些设置,如下: 生成 .py 文件: 生成代码: 1 # -*- coding: utf-8 -*-

C语言快速入门系列(三)

C语言快速入门系列(三) 结构化的程序设计 -----------------------------------转载请注明出处:coder-pig 本节引言: 在前面的学习中,我们对C语言的基本语法进行了了解,可以暂时理解成我们学了单词; 现在要做得就是学语法,也就是算法;就是构成一个一个基本的程序! 在这一节中我们要学习的是C语言中的输入输出,以及程序的三种结构(顺序,选择,循环结构) 本节学习路线图: 正文: 1.字符输入/输出函数 2.格式输入/输出函数 跟前面的单个字符的输入输出不同,

Cocos2d-x创建android项目(cocos2d-x系列三)

不例外.最显眼的就是,在文件的根目录中增加了一个名为setup.py的配置文件.运行它可以配置系统的一些环境变量. 2.创建项目 新的版本我们来动手创建一个新项目吧.找到tools文件夹....额 打包的那个名为create-project.py的文件似乎木有了!原来,在新版本中,创建新项目已经可以通过命令行来创建了,相对于先前版本的图形界面,命令行更简洁.我们要在setup.py中设置参数.以mac平台为例,我们进入到对应目录,运行脚本setup.py: Setting up cocos2d-

Apache Kafka系列(三) Java API使用

Apache Kafka系列(一) 起步 Apache Kafka系列(二) 命令行工具(CLI) Apache Kafka系列(三) Java API使用 摘要: Apache Kafka Java Client API 一.基本概念 Kafka集成了Producer/Consumer连接Broker的客户端工具,但是在消息处理方面,这两者主要用于服务端(Broker)的简单操作,如: 1.创建Topic 2.罗列出已存在的Topic 3.对已有Topic的Produce/Consume测试

Spring基础系列6 -- Spring表达式语言(Spring EL)

Spring基础系列6 -- Spring表达式语言(Spring EL) 转载:http://www.cnblogs.com/leiOOlei/p/3543222.html 本篇讲述了Spring Expression Language —— 即Spring3中功能丰富强大的表达式语言,简称SpEL.SpEL是类似于OGNL和JSF EL的表达式语言,能够在运行时构建复杂表达式,存取对象属性.对象方法调用等.所有的SpEL都支持XML和Annotation两种方式,格式:#{ SpEL exp

SQL Server 2008空间数据应用系列三:SQL Server 2008空间数据类型

原文:SQL Server 2008空间数据应用系列三:SQL Server 2008空间数据类型 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft SQL Server 2008 R2调测. 2.具备 Transact-SQL 编程经验和使用 SQL Server Management Studio 的经验. 3.熟悉或了解Microsoft SQL Server 2008中的空间数据类型. 4.具备相应的GIS专业理论知识. 5.其他相关知识. SQL Serve

Exchange Server 2013 系列三:部署规划

杜飞 通过对客户的需求进行调研分析之后就需要进行整体规划,才能保证项目的可用性.可靠性和可扩展性.在Exchange Server2013的规划涉及内容很广,在此只能是将一些常用的.基本的内容提到. 活动目录规划: Exchange 2013 向 Active Directory 域服务架构中添加了新的属性,并对现有的类和属性进行了其他修改,以满足邮件处理的基本需求.Microsoft Exchange Server 2013 将所有配置和收件人信息存储在 Active Directory 目录

Android高效率编码-第三方SDK详解系列(三)——JPush推送牵扯出来的江湖恩怨,XMPP实现推送,自定义客户端推送

Android高效率编码-第三方SDK详解系列(三)--JPush推送牵扯出来的江湖恩怨,XMPP实现推送,自定义客户端推送 很久没有更新第三方SDK这个系列了,所以更新一下这几天工作中使用到的推送,写这个系列真的很要命,你要去把他们的API文档大致的翻阅一遍,而且各种功能都实现一遍,解决各种bug各种坑,不得不说,极光推送真坑,大家使用还是要慎重,我们看一下极光推送的官网 https://www.jpush.cn/common/ 推送比较使用,很多软件有需要,所以在这个点拿出来多讲讲,我们本节

Exchange 2013SP1和O365混合部署系列三

继续,基本上大多数都是截图,在某些地方,会有一些提示. 下面就是和本地域进行同步,主要用到的是Dirsync工具. 全都是下一步. 继续下一步. 继续下一步. 这里输入的就是O365的管理员账号.也就是当时注册的那个. 本地管理员账号. 继续下一步. 开始自动配置. 开始同步本地的账户.到WAAD. 图上我们可以看到同步状态. 继续下面的操作,激活已同步的用户. 根据需要选择. 有印象没?安装同步工具的时候选的那个密码同步的选项. 先到这吧,下篇开始在本地Exchange 2013 SP1上配置