C++ User-defined Datatypes

C++中, 除了int, doubel, char 等等built-in 的datatypes, 还可以根据实际的需要, 自己定义所需的数据类型。这里介绍两种自定义的数据类型, 一个是类(class), 另一种是struct(结构体)。

C++拥有class(类)的概念,而C语言没有,这可能是C++区别于C语言最大的不同之处吧。类属于用户自定义的数据类型。其用法和int double等的数据类型的用法是基本相似的。我们可以用一个class 去声明一个对象(object,就相当于我们用int 声明一个整型变量一样。对象(objects)既有成员数据,又有成员函数。这里所说的objects适合OOPobject-oriented programing,一种很有名的,功能强大的编程范式)中的面向对像是一样的。

 

在介绍class 的概念之间,我们首先介绍一个carry-over from the C 的概念,结构体(structures)。这也是一个user defineddatatype

结构体的一个最大的特点就是将a collection of data items of diverse types。注意虽然structuresC++ 中可以拥有成员函数(member function),但是我们在这里忽略这一点(为了区分),说结构体可以被看成一个只有成员变量的对象。

结构体允许内部的各个成员变量可以属于不同的类型,这个特点尤为重要,因为这使得我们可以将相关联的变量(例如一个类的属性值),尽管变量可能属于不同的类型,我我们却可以将其封装为一个结构体。例如一个银行存款本(certificate of deposit),具有的属性我the account balance, the interest rate, the term(the number of months until maturity). 如下:

 

struct CDAccount {
   double balance;
   double interestRate;
   int term; //months until maturity
}; // 注意这个分好“;”也属于结构体定义的一部分, 必须带上, 这是容易出错的


再比如, 一个MIT的sudent 具有两个属性, 一个是name, 一个是学号, 我们可以如下定义一个结构体(user-defined datatype)

struct MITStudent {
   char* name;
   int studentID;
};


下面给出一个关于struct的例子:

#include <iostream>

using namespace std;

struct CDAccount {
   double balance;
   double interestRate;
   int term; //months until maturity
}; // 不要忘了分号, struct的一部分

void getData(CDAccount & theAccount); //passing by reference
//Postcondition: theAccount.balance, theAccount.interestRate, and
//theAccount.term have been given values that the user entered at the
//keyboard

int main() {
   CDAccount account;
   getData(account);

   double rateFraction, interest;
   rateFraction = account.interestRate/100.0;
   interest = account.balance * (rateFraction * (account.term/12.0)); //年利率, 6个月相当于乘以0.5
   account.balance = account.balance + interest;


   cout.setf(ios::fixed);
   cout.setf(ios::showpoint);
   cout.precision(2);

   cout << "When your CD matures in "
        << account.term <<" months, \n"
        << "it will have a balance of $"
        << account.balance << endl;
   return 0;
}

// Uses iostream

void getData(CDAccount& theAccount) {
   cout << "Enter account balance: $";
   cin >> theAccount.balance;
   cout << endl;
   cout << "Enter interest rate: ";
   cin >> theAccount.interestRate;
   cout << endl;
   cout << "Enter the number of months until maturity: ";
   cin >> theAccount.term;
   cout << endl;
}

运行结果如下:


 

上面测试的时候, 年利率为为0.1%

NOTE: (1)struct 结构体类型定义一般放在所有函数(包括main函数)之外, 这样, 结构体类型就是一个全局变量, 所有的函数都可以使用这个类型。

                    (2)stuct 这个用户自定义的类型里面的成员变量的access modifier 默认为public, 例如上个例子中的balance 等成员变量, 正因为如此, 我们的该结构体对象可以直接以dot operator 的方式存取自己的成员变量。例如上例中的theAccount.balance等等。

 

同一个程序中, 不同的结构体可以使用相同的成员函数名:

struct FertilizerStock {
   double quantity; //type doubel
   double nitrogenContent;
};

struct CropField {
   int quantity; // reusing member name, okay! type int
   double size;
};


 上述同名字的出现是没有问题的。例如, 我们利用二者什么两个结构体变量:

FertilizerStock superGrow;
CropField apples;

因为superGrow的quantity变量是存储在superGrow.quantity, apples 的quantity 存储在成员变量apples.quantity中的, the dot operator and the structure variable specify which quantity is meant ineach instance。

结构体变量之间的赋值(和int  , char 等变量是一致的)。

例如如果apples 和 oranges均是由结构体数据类型定义的结构体变量, 那么下面的语句时合法的:

apples = oranges;

上述语句等价于:

apples.quantity = oranges.quantity;

apples.size = oranges.size;

 

结构体类型可以作为函数的参数, 函数也可以返回一份结构体变量。 如上面的例子, 函数将现在利率变为原来的两倍如下:

CDAccount doubleInterest(CDAccount oldAccount) { // a function takes structure as an argument and returns an argument
   CDAccount temp;    temp = oldAccount;
   temp.interest.Rate = 2 * oldAccount.interestRate;
   return temp;
}

 

下面在举一个上面的程序改进后的例子:

#include <iostream>

using namespace std;

struct Date {
   int month;
   int day;
   int year;
};

// improved structure for a bank certificate of deposit
struct CDAccountNew {
   double initialBalance;
   double interestRate;
   int term; //months until maturity
   Date maturity; //date when CD matures
   double balanceAtMaturity;
};

void getCDData(CDAccountNew & theAccount); //passing by reference
//Postcondition: theAccount.initialBalance, theAccount.interestRate, and
//theAccount.term and the Account.maturity have been given values that
//the user entered at the
//keyboard

void getDate(Date& theDate);
//Postcondition: theDate.month, theDate.day, theDate.year have
//been given values that the user entered at the keyboard.


int main() {
   CDAccountNew account;
   cout << "Enter account data on the day account was opened: \n";
   getCDData(account);

   double rateFraction, interest;
   rateFraction = account.interestRate/100.0;
   interest = account.initialBalance * (rateFraction * (account.term/12.0)); //年利率, 6个月相当于乘以0.5
   account.balanceAtMaturity = account.initialBalance + interest;


   cout.setf(ios::fixed);
   cout.setf(ios::showpoint);
   cout.precision(2);

   cout << "When your CD matures on "
        << account.maturity.month << "-" << account.maturity.day
        << "-" << account.maturity.year << endl
        << "it will have a balance of $"
        << account.balanceAtMaturity << endl;
   return 0;
}



// Uses iostream

void getCDData(CDAccountNew& theAccount) {
   cout << "Enter account balance: $";
   cin >> theAccount.initialBalance;
   cout << endl;
   cout << "Enter account interest rate: ";
   cin >> theAccount.interestRate;
   cout << endl;
   cout << "Enter the number of months until maturity: ";
   cin >> theAccount.term;
   cout << endl;
   cout << "Enter the maturity date: ";
   getDate(theAccount.maturity);
}

void getDate(Date& theDate) {
   cout << endl;
   cout << "Enter month: " ;
   cin >> theDate.month;
   cout << endl;
   cout << "Enter day: ";
   cin >> theDate.day;
   cout << endl;
   cout << "Enter year: ";
   cin >> theDate.year;
}


运行结果为:

 

NOTE: 对structures的初始化, 我们可以在声明结构体类型变量的同时进行初始化:

例如:

struct Date {

   int month;

  int day;

  int year; 

};

然后我们利用上面定义的结构体数据类型声明变量:

Date dueDate = {12, 31, 2003};

按照{} 内数字的顺序给对应的结构体成员变量赋值。  对于未初始化的结构体的成员变量, 默认赋值为0.

例如:

Date dueDate = {12, 31}; // dueDate.month = 12, dueDate.day = 31; dueDate.year = 0

 


 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值