mylogo

退役程序员的茶室 RetiredCoder.cn

← 返回上一页

C++编程基础: 12. 类、对象和构造函数

2025-04-15 11:37:16

本系列文章是配合我发布的《C++编程基础》系列视频教程的知识点总结和补充。这一节我们来讲讲类、对象和构造函数。

C++引入了类似Java用到的类的概念,让它可以称为是面向对象的语言。编程语言中类的概念,和现实生活中的类很像,本节课以书为例,定义了一个叫做Book的类,书虽各有不同,但还是有些相同的特性,或称为属性,例如都有书名、作家、出版社等等,在程序中这些特性就可以被声明为类的属性或者叫类成员变量。而和这个类相关的方法,又可声明为类成员函数。

默认情况下类的属性和方法的作用域是私有private的,要想让外部访问它们,需要将它们声明为public。另外还有一种作用域介于private和public的作用域之间的类型叫做protected,属于此种作用域的属性和方法可以在基类的派生类中调用,这就牵涉到类的继承的问题了,这里暂且不说。

标记作用域的方法,是在类中将属性和方法前加上关键字“public:”或“private:”。

例如在Book类的头文件中类是这样被声明的:

class Book{
    private:    
        string name;
        string author;    
        int borrowed=0;
    public:
        Book();
        Book(string bookname, string bookauthor, int bookborrowed);
        void setName(string bookname);
        string getName();
        void setAuther(string bookauthor);
        string getAuthor();
        void setBorrowed(int bookborrowed);
        int getBorrowed();
        void printInfo();};

如果你看过了我发布的视频,一定会发现这和视频中定义的类略有不同,这是由于在视频中,我将类的定义放在了main函数所在的cpp源代码文件中,而更为规范的方法是将类的声明放在头文件里,将具体实现放在另一个和类同名的cpp文件中,在主程序中调用类时,只需在程序开头的预处理命令包含类对应的头文件。

在Xcode中,左下角点击+,在目录中点击File…

Image

在弹出窗口中选择“C++ File”后点击“Next”

Image

给出类的名字后,点击“Next”

Image

如果希望类相关文件单独存放,可以在下面的窗口中点击“New Folder”,新建一个文件夹来存放类的cpp文件和头文件hpp。

Image

选中类存放的目录后点击“Create”

Image

点击“Create”后项目左侧的目录中会多出Book.cpp和Book.hpp两个文件。

Image

在Book.hpp头文件中,代码如下:

#ifndef Book_hpp
#define Book_hpp
#include <stdio.h>
#include <string>
using namespace std;
class Book{
    private: 
        string name; 
        string author; 
        int borrowed=0;
    public: 
        Book(); 
        Book(string bookname, string bookauthor, int bookborrowed);
        void setName(string bookname); 
        string getName(); 
        void setAuther(string bookauthor); 
        string getAuthor(); 
        void setBorrowed(int bookborrowed); 
        int getBorrowed(); 
        void printInfo();
};
#endif

代码中预处理阶段运行的条件编译#ifndef…#endif结构在Xcode中是在生成头文件时自动给出的,它是为了防止项目中多个文件需要使用同一个类时出现的头文件的重复编译。

#ifndef Book_hpp#define Book_hpp...#endif 

如果不是在Xcode中自动生成的头文件,可能会是以.h为扩展名的头文件,有些人则会习惯使用大写标识(如BOOK_H),上面的3行指令会这样写:

#ifndef BOOK_H#define BOOK_H...#endif 

在Book.cpp中的代码,则是对这个类的具体定义/实现。

#include "Book.hpp"
#include <iostream>
Book::Book(){}
Book::Book(string bookname, string bookauthor, int bookborrowed=0){
    name = bookname; 
    author = bookauthor; 
    borrowed = bookborrowed;
}
void Book::setName(string bookname){
    name = bookname;
}
string Book::getName(){ 
    return name;
}
void Book::setAuther(string bookauthor){
    author = bookauthor;
}
string Book::getAuthor(){ 
    if(author.empty()){ 
        author="Unknown"; 
    } 
    return author;
}
void Book::setBorrowed(int bookborrowed){
    borrowed = bookborrowed;
}
int Book::getBorrowed(){ 
    return borrowed;
}
void Book::printInfo(){
    if(borrowed==1){
        cout<<"The book's name is "<<name<<". The author is "<<getAuthor()<<". The book's borrowed."<<endl;
    }else{ 
        cout<<"The book's name is "<<name<<". The author is "<<getAuthor()<<". The book is mine."<<endl;
    }
}

在main.cpp中程序中使用这个Book类时,只需在开头包含这个类的头文件Book.hpp即可。

#include <iostream>
#include <string>
#include "Book.hpp"
using namespace std;
int main(int argc, const char * argv[]) {
// insert code here... 
    std::cout << "Hello, World!\n";
    Book mybook; 
    std::cout <<"Before:"<<mybook.getName()<<endl; 
    std::cout <<"Before:"<<mybook.getBorrowed()<<endl; 
    mybook.setName("Harry Potter"); 
    mybook.setBorrowed(0); 
    std::cout <<"After:"<<mybook.getName()<<endl;
    std::cout <<"After:"<<mybook.getBorrowed()<<endl; 
    // mybook. 
    mybook.printInfo(); 
    Book hisbook("The Little Prince","",1);
    hisbook.printInfo(); 
    return0;
}