news 2026/5/11 6:20:42

【c++面向对象编程】第2篇:类与对象(一):定义第一个类——成员变量与成员函数

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【c++面向对象编程】第2篇:类与对象(一):定义第一个类——成员变量与成员函数

目录

一、从一个日常需求开始

二、定义你的第一个类

三、访问修饰符:public、private、protected

举个例子,看看区别:

四、成员变量怎么声明?

五、成员函数:两种实现方式

方式一:类内实现(隐式内联)

方式二:类外实现(推荐)

六、一个完整的例子:时钟类

七、常见错误(新手必踩的坑)

1. 忘了在类外实现时写类名::

2. 在private函数里访问不到外部变量(反过来也是)

3. 结构体和类的区别(面试爱问)

八、这一篇的收获


一、从一个日常需求开始

假设你要写一个程序管理图书。每本书有:书名、作者、价格。

用C的结构体,你可能会这样:

c

struct Book { char title[100]; char author[50]; double price; }; // 然后写一堆函数操作它 void printBook(struct Book* b) { ... } void discount(struct Book* b, double rate) { ... }

没什么问题,但你要记住:哪些函数能改price?改的时候要不要校验(比如价格不能为负)?随着代码变多,这些“约定”很容易被忘记。

C++的类把数据和操作绑在一起,并且控制谁能访问什么


二、定义你的第一个类

下面是一个最简单的Book类:

cpp

#include <iostream> #include <string> using namespace std; class Book { public: string title; string author; double price; void print() { cout << "书名:" << title << endl; cout << "作者:" << author << endl; cout << "价格:" << price << "元" << endl; } void setPrice(double p) { if (p >= 0) { price = p; } else { cout << "价格不能为负数!" << endl; } } };

然后这样使用:

cpp

int main() { Book b; b.title = "C++ Primer"; b.author = "Lippman"; b.setPrice(128.5); b.print(); return 0; }

你可能会说:“这不就是结构体里塞了几个函数吗?”——差不多,但多了控制权限。


三、访问修饰符:public、private、protected

上面的代码里出现了public:,它的意思是:这些东西外面可以直接访问

C++提供了三个访问修饰符:

修饰符谁能访问日常理解
public任何人公开的接口,像遥控器上的按钮
private只有类自己的成员函数内部秘密,用户碰不到
protected自己 + 子类可以传给后代,但外人不行

举个例子,看看区别:

cpp

class BankAccount { public: string owner; // 谁都能看账户名 void deposit(double money) { if (money > 0) balance += money; } double getBalance() { return balance; } private: double balance; // 余额不能直接碰 }; int main() { BankAccount acc; acc.owner = "张三"; // ✅ 可以,owner是public acc.deposit(500); // ✅ 可以,通过函数操作 acc.balance = 1000; // ❌ 编译错误!balance是private cout << acc.getBalance(); // ✅ 只能通过函数获取 }

为什么要这样?

  • balance直接暴露在外面,万一有人写acc.balance = -10000就出问题了

  • 通过deposit()函数,我们可以加校验(只能存正数)

  • 通过getBalance()只读不写(没有提供setBalance),余额就只能看不能改

封装的核心不是“藏起来”,而是“可控”


四、成员变量怎么声明?

成员变量可以像普通变量一样声明,但一般写在privateprotected区域:

cpp

class Student { private: string name; // 字符串类型 int age; // 整型 double score[5]; // 数组 int* pData; // 指针(后面讲动态内存时会用) public: // 成员函数... };

几条潜规则(不是语法强制,但建议遵守):

  1. 成员变量放在private——除非你有特殊理由

  2. 命名风格保持一致,很多人用下划线后缀:name_age_m_name

  3. 不要在类内给成员变量赋默认值(除非用C++11的类内初始化,后面会讲)


五、成员函数:两种实现方式

成员函数可以在类内直接写,也可以在类外写。

方式一:类内实现(隐式内联)

刚才的Book类就是类内实现:

cpp

class Book { public: void print() { cout << title << endl; // 直接写在类里 } };

优点:简单直观
缺点:函数体暴露在头文件里,编译依赖重(改动函数实现会重新编译所有包含头文件的代码)

方式二:类外实现(推荐)

把声明和实现分开:

cpp

// Book.h 头文件 class Book { public: void print(); // 只声明 void setPrice(double p); private: string title; string author; double price; }; // Book.cpp 实现文件 #include "Book.h" #include <iostream> using namespace std; void Book::print() { // 注意 Book:: 表示这个函数属于Book类 cout << "书名:" << title << endl; cout << "作者:" << author << endl; cout << "价格:" << price << "元" << endl; } void Book::setPrice(double p) { if (p >= 0) price = p; }

Book::print()::作用域运算符,意思是“print这个函数是Book这个类里的”。

类外实现的优点

  • 头文件只放接口,干净整洁

  • 修改函数实现时,只编译.cpp文件,不用重新编译所有依赖

  • 多人协作时可以并行开发(一个人改.h,一个人改.cpp)

对于只有三五行的简单函数(比如getBalance()),可以直接写类内;复杂的逻辑写类外。


六、一个完整的例子:时钟类

把前面知识点串起来,我们来写一个有实际意义的Clock类。

cpp

// Clock.h #ifndef CLOCK_H // 防止重复包含 #define CLOCK_H class Clock { public: void setTime(int h, int m, int s); void tick(); // 走一秒 void display(); // 显示时间 private: int hour; int minute; int second; void normalize(); // 辅助函数,处理进位(只内部用,所以private) }; #endif

cpp

// Clock.cpp #include "Clock.h" #include <iostream> #include <iomanip> using namespace std; void Clock::setTime(int h, int m, int s) { hour = h; minute = m; second = s; normalize(); // 万一传进来的数值超出范围 } void Clock::tick() { second++; normalize(); } void Clock::normalize() { if (second >= 60) { minute += second / 60; second %= 60; } if (minute >= 60) { hour += minute / 60; minute %= 60; } if (hour >= 24) { hour %= 24; } } void Clock::display() { cout << setfill('0'); cout << setw(2) << hour << ":" << setw(2) << minute << ":" << setw(2) << second << endl; }

cpp

// main.cpp #include "Clock.h" int main() { Clock c; c.setTime(23, 59, 55); for (int i = 0; i < 10; i++) { c.display(); c.tick(); } return 0; } // 输出: // 23:59:55 // 23:59:56 // ... // 00:00:04

这个例子中:

  • hourminutesecondprivate——外部不能随意篡改

  • setTimetickdisplaypublic——用户通过它们操作时钟

  • normalizeprivate——外部不需要知道“进位”的具体逻辑


七、常见错误(新手必踩的坑)

1. 忘了在类外实现时写类名::

cpp

void print() { ... } // ❌ 这是全局函数,不是Book类的 void Book::print() { ... } // ✅ 正确

2. 在private函数里访问不到外部变量(反过来也是)

成员函数可以访问本对象的任何成员(不管public还是private),但不是直接访问别的对象的私有成员。

3. 结构体和类的区别(面试爱问)

  • struct:成员默认是public

  • class:成员默认是private

除此之外,在C++里几乎没有区别。很多人用struct表示纯数据容器(像C语言那样)。


八、这一篇的收获

你现在应该能:

  • class定义一个类

  • 区分publicprivateprotected的访问权限

  • 在类内或类外实现成员函数

  • 理解封装的第一步:把数据藏起来,提供接口函数

💡 小作业:定义一个Rectangle类,有宽度和高度(private),提供setSize()getArea()getPerimeter()(public),并写一个main函数测试。


下一篇预告:第3篇《类与对象(二):构造函数与析构函数》——对象出生时自动执行的代码,和对象销毁时做的清理工作。你会发现,原来很多“初始化”和“收尾”的活儿,根本不用手动调用。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/11 6:17:49

专业内容平台的双轨制战略:从信噪比失衡到价值变现

1. 项目概述&#xff1a;当新闻业遭遇“噪音”时代“新闻业已死&#xff0c;撒上几朵百合花&#xff0c;可以开始填土了。”——这是2010年&#xff0c;一位资深媒体人在行业论坛上发出的感慨。这句话并非空穴来风&#xff0c;它精准地戳中了当时&#xff0c;乃至今天所有内容创…

作者头像 李华
网站建设 2026/5/11 6:17:48

图神经网络在边缘计算中的物理场重建应用

1. 图神经网络与边缘计算背景解析在工业物联网和数字孪生系统中&#xff0c;物理场重建是一个核心挑战。传统基于有限元或计算流体力学(CFD)的方法虽然精度高&#xff0c;但计算复杂度使得它们难以在资源受限的边缘设备上实时运行。以核电站热工水力监测为例&#xff0c;常规CF…

作者头像 李华
网站建设 2026/5/11 6:13:14

联发科2012年崛起:从功能机到智能机的转型与挑战

1. 从功能机到智能机的惊险一跃&#xff1a;联发科的2012年2012年&#xff0c;对于全球移动芯片行业来说&#xff0c;是几家欢喜几家愁的一年。诺基亚和黑莓的持续衰落&#xff0c;直接拖垮了像ST-Ericsson这样深度绑定的芯片供应商&#xff1b;即便是巨头如高通&#xff0c;也…

作者头像 李华
网站建设 2026/5/11 6:12:31

AI编码助手技能库:结构化提示词提升开发效率与代码质量

1. 项目概述&#xff1a;一个为AI编码助手打造的“技能库”生态如果你和我一样&#xff0c;每天都在和Claude Code、Cursor、GitHub Copilot这些AI编码助手打交道&#xff0c;那你肯定也经历过这样的时刻&#xff1a;想让AI帮你写个单元测试&#xff0c;或者做个安全审计&#…

作者头像 李华
网站建设 2026/5/11 6:11:38

从零部署私有化AI对话框架:igogpt架构解析与实战指南

1. 项目概述与核心价值最近在折腾AI应用部署的朋友&#xff0c;可能都听说过一个词叫“套壳ChatGPT”。这类项目通常是把OpenAI的API接口包装一下&#xff0c;做个Web界面&#xff0c;让用户能更方便地使用。但今天要聊的这个项目——igolaizola/igogpt&#xff0c;它给我的感觉…

作者头像 李华
网站建设 2026/5/11 6:10:36

福特自动驾驶测试车:机器人如何革新汽车耐久性测试

1. 项目概述&#xff1a;福特自动驾驶测试车的幕后故事如果你在汽车行业待过&#xff0c;或者对车辆耐久性测试有所了解&#xff0c;那你一定知道“搓板路”、“比利时路”这些名字听起来就让人牙酸的测试项目。想象一下&#xff0c;每天开着车以15英里每小时的速度&#xff0c…

作者头像 李华