一、"类" 的介绍
在C++中, 用 "类" 来描述"对象", 所谓的"对象"是指现实世界中的一切事物。那么类就可以看做是对相似事物的抽象, 找到这些不同事物间的共同点, 如自行车和摩托车, 首先他们都属于"对象", 并且具有一定得相同点, 和一些不同点, 相同点如他们都有质量、都有两个轮子, 都是属于交通工具等。"都有质量"、"两个轮子"属于这个对象的属性, 而"都能够当做交通工具"属于该对象具有的行为, 也称方法。
类是属于用户自定义的数据类型, 并且该类型的数据具有一定的行为能力, 也就是类中说描述的方法。通常来说, 一个类的定义包含两部分的内容, 一是该类的属性, 另一部分是它所拥有的方法。以 "人类" 这个类来说, 每个人都有自己的姓名、年龄、出生日期、体重等, 为 人类 的属性部分, 此外, 人能够吃饭、睡觉、行走、说话等属于人类所具有的行为。
上面举例中所描述的 "人" 类仅仅是具有人这种对象的最基础的一些属性和行为, 可以称之为人的"基类"。 再说说一些具有一些职业的人, 例如学生, 一个学生还具有"基类"中所没有的属性, 如学校、班级、学号; 也可以具有基类所不具有的行为, 如每天需要去上课, 需要考试等。
学生类可以看做是基类的一个扩展, 因为他具有基类的所有属性和行为, 并且在此基础上增加了一些基类所没有的属性和行为, 像"学生"这样的类称为"人类"这个基类的"派生类"或者"子类"。在学生的基础上海可以进一步的扩展出其他更高级的类, 如"研究生"类。
到此, 我们不再更深的去介绍类的其他相关知识。
二:类的使用
类是创建对象的模板,一个类可以创建多个对象,每个对象都是类类型的一个变量;创建对象的过程也叫类的实例化。每个对象都是类的一个具体实例(Instance),拥有类的成员变量和成员函数。
与结构体一样,类只是一种复杂数据类型的声明,不占用内存空间。而对象是类这种数据类型的一个变量,占用内存空间。
类的声明
类是用户自定义的类型,如果程序中要用到类,必须先进行声明,或者使用已存在的类(别人写好的类、标准库中的类等),C++语法本身并不提供现成的类的名称、结构和内容。
一个简单的类的定义:
class Stock { //class declaration
private: //默认使用关键字private
std::stringcompany;
longshares;
doubleshare_val;
doubletotal_val;
voidset_tot() { total_val = shares * share_val; } //类中声明的函数自动成为内联函数
//voidset_tot(); //defination kept separate
public:
Stock();
Stock(conststd::string &co, long n, double pr);
~Stock();
voidacquire(const std::string &co, long n, double pr);
voidbuy(long num, double price);
voidsell(long num, double price);
voidupdate(double price);
voidshow() const; //promises not to change invoking object
}; //note semicolon at the end
该例创建了一个Stock类,它包含了4个成员变量。
class是C++中的关键字,用于声明一个类;紧接 class 关键字之后的是我们自定义的类名 Stock;由{ }包围的是类体。声明类时不能对成员变量进行初始化,只有在创建对象以后才能赋值。
类可以理解为一种新的数据类型,该数据类型的名称是 Stock。与 char、int、float 等基本数据类型不同的是,Student 是一种复杂数据类型,可以包含基本类型,而且多了很多基本类型中没有的特性。
需要注意的是:在类声明的最后有一个分号(;),它是类声明的一部分,表示类声明结束了,不能省略。
创建对象
声明了Stock 数据类型之后,就可以用它来定义变量了,如:
Stock s1 //创建对象
该语句声明了一个名字为 s1、数据类型为 Stock 的变量。这和:
int a; //定义整形变量
语句定义了一个整型变量表达的意思是类似的。而 s1 这个变量我们称之为 Student 类的对象。
在定义类的对象时,class 关键字可要可不要。但出于习惯我们通常都会省略掉class关键字,例如:
1. class Stock s1; //正确
2. Stock s1; //同样正确
创建类的对象时,除了能定义单个变量以外,还可以定义一个数组或者指针。例如:
1. Stock all_stock[100];
2. Stock *pointer;
第一条语句定义了一个 all_stock 数组,该数据拥有100个元素,每个元素都是 Stock 类型。第二条语句定义了一个 Stock 类型的指针 pointer,该指针可以指向 Stock 类型的变量(对象),用法和普通指针一样。
声明类的同时创建对象
和结构体(struct)类似,你可以先声明类,然后再创建对象,也可以在声明类的同时创建对象。如下所示:
class Person{
public:
//成员变量
char *name;
int age;
double weight;
//成员函数
void say(){
std::cout << "我是" << name << ",今年" << age << "岁,体重" << weight << std::endl;
}
}p1, p2;
这个时候你也可以省略类名,直接创建对象。
直接定义对象,在C++中是合法的、允许的,但却很少用,也不提倡用。
一个完整的示例:
头文件:person.h
#ifndef PERSON_H_
#define PERSON_H_
class Person {
public:
//成员变量
char*name;
intage;
doubleweight;
//成员函数
voidsay() {
std::cout << "我是" << name <<",今年" << age<< "岁,体重" << weight <<std::endl;
}
};
#endif PERSON_H_
源文件main.cpp
#include <iostream>
#include "person.h";
int main() {
//创建对象
Person p1;
p1.name ="张三";
p1.age = 25;
p1.weight =60.00;
p1.say();
//定义指针
Person *p2 =&p1;
p2->name ="李四";
p2->age =50;
p2->weight= 68.94;
p2->say();
system("pause");
return 0;
}
运行结果:
public 是C++中的关键字,用来修饰成员变量和成员函数,表示它们是公有的。只有 public 后面的成员变量和成员函数才能被创建的对象访问到,没有使用 public,那么创建对象后就不能使用任何成员。
main 函数中首先创建了一个对象 p1,然后又定义了一个Person 类型的指针变量。可以发现,和结构体(struct)类似,一个对象通过成员选择符”.“来访问成员变量和成员函数,而指针变量通过指针操作符”->“来访问成员。
注意:对象指针指向的是一个具体的对象,而不是类。下面的写法是错误的:
Person *p1;
p1 = &Person;
对象的作用域、可见域与生存周期
类对象的作用域、可见域以及生存周期与普通变量的保持相同, 当对象生存周期结束时对象被自动撤销, 所占用的内存被回收, 需要注意的是, 如果对象的成员函数中有使用 new 或者 malloc申请的动态内存程序不会对其进行释放, 需要我们手动进行清理, 否则会造成内存泄露。
C++用new和不用new创建对象区别
起初刚学C++时,很不习惯用new,后来看老外的程序,发现几乎都是使用new,想一想区别也不是太大,但是在大一点的项目设计中,有时候不使用new的确会带来很多问题。当然这都是跟new的用法有关的。new创建对象,使用完后需使用delete删除,跟申请内存类似。所以,new有时候又不太适合,比如在频繁调用场合,使用局部new对象就不是个好选择,使用全局类对象或一个经过初始化的全局类指针似乎更加高效。
一、new创建类对象与不new区别
下面是自己总结的一些关于new创建对象特点:
new创建对象需要指针接收,一处初始化,多处使用
new创建对象使用完需delete销毁
new创建对象直接使用堆空间,而局部不用new定义对象则使用栈空间
new对象指针用途广泛,比如作为函数返回值、函数参数等
频繁调用场合并不适合new,就像new申请和释放内存一样
二、new创建类对象实例
1、new创建对象例子:
CTest* pTest = new CTest();
delete pTest;
pTest用来接收对象指针。
不用new,直接使用类定义申明:
CTest mTest;
此种创建方式,使用完后不需要手动释放,该类析构函数会自动执行。而new申请的对象,则只有调用到delete时再会执行析构函数,如果程序退出而没有执行delete则会造成内存泄漏。
2、只定义类指针
这跟不用new申明对象有很大区别,类指针可以先行定义,但类指针只是个通用指针,在new之前并不为该类对象分配任何内存空间。比如:
CTest* pTest = NULL;
但使用普通方式创建的类对象,在创建之初就已经分配了内存空间。而类指针,如果未经过对象初始化,则不需要delete释放。
3、new对象指针作为函数参数和返回值
下面是随手写一个例子,不太严谨。主要示意一下类指针对象作为返回值和参数使用。
#include<iostream>
using namespacestd;
class TestA {
public:
int a;
TestA() {
cout << "TestA的默认构造函数" <<endl;
}
~TestA() {
cout << "TestA的析构函数" <<endl;
}
};
class TestB {
public:
int b;
TestB() {
cout << "TestB的默认构造函数" <<endl;
}
~TestB() {
cout << "TestB的析构函数" <<endl;
}
};
TestA* fun(TestB*pb) {
TestA* pa = new TestA();
pa->a = pb->b;
return pa;
}
int main() {
TestA* pa = new TestA();
TestB* pb = new TestB();
pb->b = 20;
TestA* pRes = fun(pb);
if(pa != NULL) {
delete pa;
}
if(pb != NULL) {
delete pb;
}
if(pRes != NULL) {
delete pRes;
}
system("pause");
return 0;
}
结果: