栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

1.3 C++基础知识

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

1.3 C++基础知识

本节讨论C++的程序结构。

在类外部定义函数

之前将函数在类中定义,现在首先将函数定义到类的外部,仅在类中申明。

注意定义在外部的函数,函数名前面需要加上Person::,表示属于Person类,其他规则和在类中定义一致。

单模块处理

当函数内容比较简短时,写在类中也可以,但是如果篇幅较大,最好还是在外部实现,这样代码会更简洁些。

假设一个团队在做某个设备:

  • 由A实现Person类(相当于Person模块);
  • 由B实现main,B会在main中使用Person类,但是不会关心Person类的具体实现,只关心怎么使用这个类;

那么,A需要创建两个文件:

  1. person.h
  2. person.cpp

其中头文件 person.h 需要提供给B使用,person.cpp 则由A自行保管维护即可。

B只需要实现一个文件 main.cpp 即可,在 main.cpp 文件中 include person.h 文件,然后使用person类。

person.h

person.h 的内容如下,在头文件中,只是定义了一个Person类。

通过person.h头文件,可以看到,Person类中的有私有成员name,age,也有公有成员setName函数和printfInfo函数。

这样,使用Person类的人就能很方便的知道,要想设置name,就需要通过setName函数,而不需要关心具体的函数实现。

#ifndef __PERSON_H_
#define __PERSON_H_

class Person {
private:
    char *name;
    int age;

public:
    void setName(char *name);

    void printfInfo();
};

#endif
person.cpp

person.cpp的内容如下,在cpp文件中,include person.h文件,然后实现Person类中的函数。

#include 
#include "person.h"

#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))

void Person::setName(char *name) {
    this->name = name;
}

void Person::printfInfo() {
    printf("name = %s, age = %dn", name, age);
}
 main.cpp

在main.cpp中,通过person.h将Person类包含进来,然后就可以使用person类了。

#include 
#include "person.h"

int main(int argc, char **argv)
{
    Person per;

    per.setName("zhangsan");
    per.printfInfo();
}
Makefile

通过一个Makefile来实现编译和清除。

$^ 表示所有的依赖,$< 表示第一个依赖。

target=person

$(target): main.o person.o
    g++ -o $@ $^

%.o : %.cpp
    g++ -c -o $@ $<

clean:
    rm -f *.o $(target)

编译出来执行elf文件,结果符合预期,程序改写成功。

多模块处理

假设需要新增一个功能模块Dog,由C负责,那么团队的分工则变为:

  • 由A实现Person类;
  • 由B实现main,B会在main中使用Person/Dog类,但是不会关心Person/Dog类的具体实现,只关心怎么使用Person/Dog类;
  • 由C实现Dog类;

类似的,C需要实现两个文件:

  1. dog.h
  2. dog.cpp

与 person 类似,在dog.h中声明一个dog类,在dog.cpp中实现dog类。

dog.h
#ifndef __DOG_H_
#define __DOG_H_

class Dog {
private:
    char *name;
    int age;

public:
    void setName(char *name);

    void printfInfo();
};

#endif
dog.cpp
#include 
#include "dog.h"

#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))

void Dog::setName(char *name) {
    this->name = name;
}

void Dog::printfInfo() {
    printf("name = %s, age = %dn", name, age);
}
main.cpp

修改main.cpp,将dog.h包含进来,然后就可以使用Dog类了。

 #include 
 #include "person.h"
 #include "dog.h"

 int main(int argc, char **argv)
 {
     Person per;
     Dog dog;

     per.setName("zhangsan");
     per.printfInfo();

     dog.setName("wangcai");
     dog.printfInfo();
 }
命名空间(namespace)

假设,需要在person.cpp和dog.cpp中,分别实现一个printVersion函数,打印对应模块的版本号。

 在person.h和dog.h中申明printVersion函数,注意并不是在类中声明。

然后在main.cpp中调用。

此时,编译程序会报错,这是由于在dog.h和person.h中都有定义printVersion函数,编译器不知道要调用哪一个printVersion。

这个问题就涉及到命名空间了。

在实际工程中,可能会遇见相同名称的函数,当编译器遇见相同名称的函数时,需要根据命名空间来决定使用哪个函数。

首先修改person.h,dog.h,person.cpp,dog.cpp,分别设置两个作用域A和C。

 

 这时候编译就会报错,因为没有标明使用的是哪个域,编译器会报找不到类型声明。

 为了方便起见,将多余的代码先注释掉。

 

函数前面的A::和C::分别表示这个函数属于A和C的命名空间,声明命名空间后,代码可以编译成功,执行结果也符合预期。

类似的,也可以通过using namespace来决定要使用哪个命名空间,这时候,不冲突的对象可以不用加A::和C::,冲突的函数与之前一样,需要声明使用的命名空间是哪个。

 

 如果只要要使用某个命名空间中的某个对象,而不是全部的话,也可以单独using那个类。

 执行结果和之前是一样的。

小结

程序结构如下:

  1. 类定义(.h) / 类实现(.cpp);
  2. 命名空间;
    1. 在.h/.cpp文件中,使用namespace a { ... }设置命名空间;
    2. 在调用者源文件中:
      1. 直接使用:a::fun, a::fun2
      2. using声明:using a::fun; //以后调用fun即表示a::fun
      3. using编译:using namespace a;//以后直接调用fun,fun2即可
使用iostream

最后,再修改一下代码。

在C++中,通常使用 iostream 而不是stdio.h。

使用iostream,需要用cout替换printf,并且需要使用命名空间std。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/947489.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号