静态成员与友元函数

 

有缘

class Point {
    private:
    double x, y;
public:
    Point(double xx, double yy) ;

    friend double Distance(Point &a, Point &b);
};

Point::Point(double xx, double yy) {
    x = xx;
    y = yy;
}

double Distance(Point &a, Point &b) {
    return sqrt(pow(a.x - b.x, 2) + pow(a.y - b.y, 2));
}

类的友元函数是定义在类外部,但有权访问类的所有私有(private)成员和保护(protected)成员。尽管友元函数的原型有在类的定义中出现过,但是友元函数并不是成员函数。

友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类,在这种情况下,整个类及其所有成员都是友元。

如果要声明函数为一个类的友元,需要在类定义中该函数原型前使用关键字 friend,如下所示:

class Box
{
   double width;
public:
   double length;
   friend void printWidth( Box box );
   void setWidth( double wid );
};

声明类 ClassTwo 的所有成员函数作为类 ClassOne 的友元,需要在类 ClassOne 的定义中放置如下声明:

friend class ClassTwo;

实例

class Box{
   double width;
public:
   friend void printWidth( Box box );
   void setWidth( double wid );
};
// 成员函数定义
void Box::setWidth( double wid )
{
    width = wid;
}
// 请注意:printWidth() 不是任何类的成员函数
void printWidth( Box box )
{
   /* 因为 printWidth() 是 Box 的友元,它可以直接访问该类的任何成员 */
   cout << "Width of box : " << box.width <<endl;
}
// 程序的主函数
int main( ){
   Box box;
   // 使用成员函数设置宽度
   box.setWidth(10.0);
   // 使用友元函数输出宽度
   printWidth( box );
   return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

Width of box : 10

我们可以使用 static 关键字来把类成员定义为静态的。当我们声明类的成员为静态时,这意味着无论创建多少个类的对象,静态成员都只有一个副本。

静态成员在类的所有对象中是共享的。如果不存在其他的初始化语句,在创建第一个对象时,所有的静态数据都会被初始化为零。我们不能把静态成员的初始化放置在类的定义中,但是可以在类的外部通过使用范围解析运算符 :: 来重新声明静态变量从而对它进行初始化,如下面的实例所示。

下面的实例有助于更好地理解静态成员数据的概念:

class Box
{
   public:
      static int objectCount;
      // 构造函数定义
      Box(double l=2.0, double b=2.0, double h=2.0)
      {
         cout <<"Constructor called." << endl;
         length = l;
         breadth = b;
         height = h;
         // 每次创建对象时增加 1
         objectCount++;
      }
      double Volume()
      {
         return length * breadth * height;
      }
   private:
      double length;     // 长度
      double breadth;    // 宽度
      double height;     // 高度
};
 
// 初始化类 Box 的静态成员
int Box::objectCount = 0;
 
int main(void)
{
   Box Box1(3.3, 1.2, 1.5);    // 声明 box1
   Box Box2(8.5, 6.0, 2.0);    // 声明 box2
 
   // 输出对象的总数
   cout << "Total objects: " << Box::objectCount << endl;
 
   return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:

Constructor called.
Constructor called.
Total objects: 2

如果把函数成员声明为静态的,就可以把函数与类的任何特定对象独立开来。静态成员函数即使在类对象不存在的情况下也能被调用,静态函数只要使用类名加范围解析运算符 :: 就可以访问。

静态成员函数只能访问静态成员数据、其他静态成员函数和类外部的其他函数。

静态成员函数有一个类范围,他们不能访问类的 this 指针。您可以使用静态成员函数来判断类的某些对象是否已被创建。

静态成员函数与普通成员函数的区别:

  • 静态成员函数没有 this 指针,只能访问静态成员(包括静态成员变量和静态成员函数)。
  • 普通成员函数有 this 指针,可以访问类中的任意成员;而静态成员函数没有 this 指针。

 

class Box
{
   public:
      static int objectCount;
      // 构造函数定义
      Box(double l=2.0, double b=2.0, double h=2.0)
      {
         cout <<"Constructor called." << endl;
         length = l;
         breadth = b;
         height = h;
         // 每次创建对象时增加 1
         objectCount++;
      }
      double Volume()
      {
         return length * breadth * height;
      }
      static int getCount()
      {
         return objectCount;
      }
   private:
      double length;     // 长度
      double breadth;    // 宽度
      double height;     // 高度
};
 
// 初始化类 Box 的静态成员
int Box::objectCount = 0;
 
int main(void)
{
  
   // 在创建对象之前输出对象的总数
   cout << "Inital Stage Count: " << Box::getCount() << endl;
 
   Box Box1(3.3, 1.2, 1.5);    // 声明 box1
   Box Box2(8.5, 6.0, 2.0);    // 声明 box2
 
   // 在创建对象之后输出对象的总数
   cout << "Final Stage Count: " << Box::getCount() << endl;
 
   return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:

Inital Stage Count: 0
Constructor called.
Constructor called.
Final Stage Count: 2

1. 定义位置不同。静态成员属于类的一部分,定义在类内。友元函数是在类外定义的,通过友元声明使其成为类的友元。2. 访问权限不同。静态成员可以直接访问私有成员,它自身也具有类的访问权限。友元函数可以访问私有成员,但它自身的访问权限由定义它的作用域决定。3. 与对象的关系不同。静态成员属于类,和具体对象无关。友元函数是独立的函数,只是被授予了访问私有成员的权限。4. 继承不同。派生类会继承父类的静态成员,但不会继承父类的友元声明。5. 调用不同。静态成员用作用域运算符 :: 调用。友元函数直接调用。


 

 

class Account {
private:
    static float count; // 账户总余额
    static float interestRate;
    string accno, accname;
    float balance=0; // 账户余额

public:
    Account(string ac, string na, float ba);
    ~Account();
    void deposit(float amount); // 存款
    void withdraw(float amount); // 取款
    [[nodiscard]] float getBalance() const; // 获取账户余额
    void show(); // 显示账户所有基本信息
    static float getCount(); // 获取账户总余额
    static void setInterestRate(float rate); // 设置利率
    static float getInterestRate(); // 获取利率
    friend void update(Account& a); // 友元函数,结息
    Account();
};

float Account::count = 0;
float Account::interestRate = 0;

Account::Account(string ac, string na, float ba):
accno(std::move(ac)), accname(std::move(na)), balance(ba) {count++;}

Account::~Account() {
    count--; 
}

void Account::deposit(float amount) {//实现存款函数
    balance += amount;
}

void Account::withdraw(float amount) {//实现取款函数
    if (balance >= amount)
        balance -= amount;
    else
        cout << "wrong" << endl;

}

float Account::getBalance() const {
    return balance;
}

void Account::show() {
    cout << accno << " " << accname << " "<< balance ;
}


float Account::getCount() {
    return count;
}

void Account::setInterestRate(float rate) {
    interestRate = rate;
}

float Account::getInterestRate() {
    return interestRate;
}


void update(Account& a) {
    a.balance += a.balance * Account::getInterestRate();
}

Account::Account() = default;

int main() {
    float rate;
    float amount;
    int count;
    cin >> rate >> count;
    Account::setInterestRate(rate);
    Account **p;
    p = new Account *[count];
    for (int i = 0; i < count; i++) {
        string accno, accname;
        float balance, deposit, withdraw;
        cin >> accno >> accname >> balance >> deposit >> withdraw;
        p[i] = new Account(accno, accname, balance);
        p[i]->deposit(deposit);
        p[i]->show();
        update(*p[i]);
        cout << " " << p[i]->getBalance() ;
        p[i]->withdraw(withdraw);
        cout <<" " <<p[i]->getBalance() << endl;
        amount += p[i]->getBalance();
        delete p[i];
    }
    cout << amount << endl;
    delete[] p;
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值