C++入门10 -- 友元,内部类,运算符重载

2021-08-14  本文已影响0人  YanZi_33

友元

#include <iostream>

using namespace::std;

//class Person {
//
//public:
//    //声明并初始化
//    int m_age = 0;
//    //定义虚函数
//    virtual void run(){
//
//    }
//
//    Person(int age = 0) : m_age(age){
//        cout << "Person() " << endl;
//    }
//};

class Point {
    int m_x;
    int m_y;
public:
    Point(int x,int y) : m_x(x),m_y(y){ }
    
    int getX() const {
        return this->m_x;
    }
    
    int getY() const {
        return this->m_y;
    }
    //友元函数
    friend Point add(const Point &,const Point &);
    //友元类
    friend class Math;
};

Point add(const Point &point1,const Point &point2){
    return Point(point1.m_x + point2.m_x,point1.m_y + point2.m_y);
}

class Math {
    
public:
    Point sub(const Point &point1,const Point &point2){
        return Point(point1.m_x - point2.m_x,point1.m_y - point2.m_y);
    }
};

int main(int argc, const char * argv[]) {
    
    Point p1(10,20);
    Point p2(20,30);
    
    Point p = add(p1, p2);
    
    return 0;
}

内部类

#include <iostream>

using namespace::std;

class Person {
    int m_age;
    
public:
    static int ms_legs;
    
    Person(){
        cout << "Person()" << endl;
    }
    //内部类Car
    class Car {
        int m_price;
    public:
        Car(){
            cout << "Car()" << endl;
        }
        void run(){
            Person person;
            person.m_age = 20;
            
            ms_legs = 4;
        }
    };
};

int Person::ms_legs = 2;


class Point {

public:
    //内部类Math
    class Math {
    public:
        void test();
    };
};

//内部类声明与实现分离
void Point::Math::test(){
    
}

int main(int argc, const char * argv[]) {

    Person person;
    //内部类
    Person::Car car;
    
    return 0;
}

局部类

#include <iostream>

void test(){
    int age = 10;
    static int s_age = 30;
    //局部类
    class Person{
        void run(){
            s_age = 40;
            age = 20; //报错
        }
    };
}

int main(int argc, const char * argv[]) {
    
    return 0;
}

运算符重载

#include <iostream>

using namespace::std;

class Point {
public:
    int m_x;
    int m_y;
    
    Point(int x,int y) : m_x(x),m_y(y){ }
    void display(){
        cout << this->m_x << "-" << this->m_y << endl;
    }
    friend Point operator+(const Point &,const Point &);
};
//运算符重载
Point operator+(const Point &p1,const Point &p2){
    return Point(p1.m_x + p2.m_x,p1.m_y + p2.m_y);
}

int main(int argc, const char * argv[]) {
    
    Point p1(10,20);
    Point p2(20,30);
   
    Point p3 = p1 + p2;
    p3.display();
    
    return 0;
}
#include <iostream>

using namespace::std;

class Point {
public:
    int m_x;
    int m_y;
    
    Point(int x,int y) : m_x(x),m_y(y){ }
    void display(){
        cout << this->m_x << "-" << this->m_y << endl;
    }
    
    //运算符重载
    Point operator+(const Point &p){
        return Point(this->m_x + p.m_x,this->m_y + p.m_y);
    }
};

int main(int argc, const char * argv[]) {
    
    Point p1(10,20);
    Point p2(20,30);
    
    Point p3 = p1 + p2;
    p3.display();
    
    return 0;
}
//  Point.hpp
//  C++34_运算符重载
//
//  Created by ljj on 8/15/21.
//

#ifndef Point_hpp
#define Point_hpp

#include <stdio.h>
#include <iostream>

using namespace::std;

class Point {
public:
    //友元函数
    friend ostream &operator<<(ostream &,const Point &);
    
    int m_x;
    int m_y;
    
    //构造函数
    Point(int x,int y) : m_x(x),m_y(y){ }
    
    //运算符重载
    Point operator+(const Point &p);
    Point operator-(const Point &p);
    Point &operator+=(const Point &p);
    
    bool operator==(const Point &p);
    bool operator!=(const Point &p);
    
    //返回的point对象 不允许赋值
    const Point operator-() const;
    
    //前++
    Point &operator++();
    
    //后++ 返回值不可修改
    const Point operator++(int);
};

#endif /* Point_hpp */
//  Point.cpp
//  C++34_运算符重载
//
//  Created by ljj on 8/15/21.
//

#include "Point.hpp"

//运算符重载
Point Point::operator+(const Point &p){
    return Point(this->m_x + p.m_x,this->m_y + p.m_y);
}

Point Point::operator-(const Point &p){
    return Point(this->m_x - p.m_x,this->m_y - p.m_y);
}

Point &Point::operator+=(const Point &p){
    this->m_x += p.m_x;
    this->m_y += p.m_y;
    return *this;
}

bool Point::operator==(const Point &p){
    return (this->m_x == p.m_x && this->m_y == p.m_y);
}

bool Point::operator!=(const Point &p){
    return (this->m_x != p.m_x || this->m_y != p.m_y);
}

//返回的point对象 不允许赋值
const Point Point::operator-() const {
    return Point(-this->m_x,-this->m_y);
}

//前++
Point &Point::operator++(){
    this->m_x++;
    this->m_y++;
    return *this;
}

//后++ 返回值不可修改
const Point Point::operator++(int){
    Point point(this->m_x,this->m_y);
    this->m_x++;
    this->m_y++;
    return point;
}

//友元函数
ostream &operator<<(ostream &cout,const Point &point){
    return cout << point.m_x << "," << point.m_y;
}
//  main.cpp
//  C++34_运算符重载
//
//  Created by ljj on 8/14/21.
//

#include <iostream>
#include "Point.hpp"

using namespace::std;


int main(int argc, const char * argv[]) {
    
    Point p1(10,20);
    Point p2(20,30);
    
    Point p3 = p1 + p2;
    cout << p3 << endl;
    
    Point p4 = p1 - p2;
    cout << p4 << endl;
    
    ++p1;
    cout << p1 << endl;
    
    p2++;
    cout << p2 << endl;
    
    return 0;
}
运算符重载实战
//  String.hpp
//  C++35_运算符重载(String)
//
//  Created by ljj on 8/15/21.
//

#ifndef String_hpp
#define String_hpp

#include <stdio.h>
#include <iostream>

using namespace::std;

class String {
    friend ostream &operator<<(ostream &,const String &);
private:
    //C语言字符串
    char *m_cstring;
public:
    //单参数构造函数
    String(const char *ctring);
    
    ~String();
    
    String &operator=(const char *cstring);
};

#endif /* String_hpp */
#include "String.hpp"

String::String(const char *cstring){
    cout << "String::String(const char *cstring)" << endl;
    if (!cstring) return;
    this->m_cstring = new char[strlen(cstring)+1]{};
    strcpy(this->m_cstring, cstring);
}

String::~String(){
    cout << "String::~String()" << endl;
    if (!this->m_cstring) return;
    delete [] this->m_cstring;
    this->m_cstring = NULL;
}

String &String::operator=(const char *cstring){
    //释放旧的字符串
    if (this->m_cstring){
        cout << "delete [] 释放旧的字符串 = " << this->m_cstring << endl;
        delete [] this->m_cstring;
        this->m_cstring = NULL;
    }
    //指向新的字符串
    if (cstring){
        this->m_cstring = new char[strlen(cstring)+1]{};
        strcpy(this->m_cstring, cstring);
        cout << "new [] 指向新的字符串 = " << cstring <<  endl;
    }
    return *this;
}

ostream &operator<<(ostream &cout,const String &string){
    if (!string.m_cstring) return cout;
    return cout << string.m_cstring;
}
第一种调用情况如下:
#include <iostream>
#include "String.hpp"

using namespace::std;

int main(int argc, const char * argv[]) {
    //直接调用构造函数
    String str1("333");
    cout << str1 << endl;
    
    //隐式调用单参数构造函数
    String str2 = "123";
    cout << str2 << endl;
    
    //隐式调用单参数构造函数
    char name[] = "444";
    String str3 = name;
    cout << str3 << endl;
    
    return 0;
}
第二种调用情况:
#include <iostream>
#include "String.hpp"

using namespace::std;

int main(int argc, const char * argv[]) {
    
    //隐式调用单参数构造函数
    String str2 = "123";
    cout << str2 << endl;
    
    //重新赋值
    str2 = "666";
    cout << str2 << endl;
    
    return 0;
}
Snip20210815_165.png
String &String::operator=(const char *cstring){
    //释放旧的字符串
    if (this->m_cstring){
        cout << "delete [] 释放旧的字符串 = " << this->m_cstring << endl;
        delete [] this->m_cstring;
        this->m_cstring = NULL;
    }
    //指向新的字符串
    if (cstring){
        this->m_cstring = new char[strlen(cstring)+1]{};
        strcpy(this->m_cstring, cstring);
        cout << "new [] 指向新的字符串 = " << cstring <<  endl;
    }
    return *this;
}
第三种调用情况:
#include <iostream>
#include "String.hpp"

using namespace::std;

int main(int argc, const char * argv[]) {
    //隐式调用单参数构造函数
    String str1 = "111";
    String str2 = "123";
    
    str1 = str2;
    
    return 0;
}
String &String::operator=(const String &string){
    return operator=(string.m_cstring);
}
第四种调用情况:
#include <iostream>
#include "String.hpp"

using namespace::std;

int main(int argc, const char * argv[]) {
    //隐式调用单参数构造函数
    String str1 = "111";
    String str2 = "123";
    
    str1 = str1;
    
    return 0;
}
Snip20210815_166.png
String &String::operator=(const char *cstring){
    //指向相同的堆空间 直接返回
    if (this->m_cstring == cstring) return *this;
    //释放旧的字符串
    if (this->m_cstring){
        cout << "delete [] 释放旧的字符串 = " << this->m_cstring << endl;
        delete [] this->m_cstring;
        this->m_cstring = NULL;
    }
    //指向新的字符串
    if (cstring){
        this->m_cstring = new char[strlen(cstring)+1]{};
        strcpy(this->m_cstring, cstring);
        cout << "new [] 指向新的字符串 = " << cstring <<  endl;
    }
    return *this;
}
第五种调用情况:
#include <iostream>
#include "String.hpp"

using namespace::std;

int main(int argc, const char * argv[]) {
    //隐式调用单参数构造函数
    String str1 = "111";
    
    //拷贝构造函数 默认浅拷贝
    String str2 = str1;
    
    return 0;
}
String::String(const String &string){
//    this->m_cstring = string.m_cstring;
    operator=(string.m_cstring);
//    *this = string.m_cstring;
}
//  String.hpp
//  C++35_运算符重载(String)
//
//  Created by ljj on 8/15/21.
//

#ifndef String_hpp
#define String_hpp

#include <stdio.h>
#include <iostream>

using namespace::std;

class String {
    friend ostream &operator<<(ostream &,const String &);
private:
    //C语言字符串
    char *m_cstring;
    
public:
    //单参数构造函数
    String(const char *cstring);
    
    //拷贝构造函数
    String(const String &string);
    
    ~String();
    
    //C语言字符串
    String &operator=(const char *cstring);
    //String字符串
    String &operator=(const String &string);
};


#endif /* String_hpp */
//  String.cpp
//  C++35_运算符重载(String)
//
//  Created by ljj on 8/15/21.
//

#include "String.hpp"

String::String(const char *cstring){
    if (!cstring) return;
    cout << "String::String(const char *cstring) -- new " << cstring << endl;
    this->m_cstring = new char[strlen(cstring)+1]{};
    strcpy(this->m_cstring, cstring);
}

String::String(const String &string){
//    this->m_cstring = string.m_cstring;
    operator=(string.m_cstring);
//    *this = string.m_cstring;
}

String::~String(){
//    if (!this->m_cstring) return;
//    cout << "String::~String() delete" << this->m_cstring << endl;
//    delete [] this->m_cstring;
//    this->m_cstring = NULL;
    
    operator=(NULL);
    //将NULL赋值给当前对象 等价写法
//    *this = NULL;
//    (*this).operator=(NULL);
//    this->operator=(NULL);
}

String &String::operator=(const char *cstring){
    //指向相同的堆空间 直接返回
    if (this->m_cstring == cstring) return *this;
    //释放旧的字符串
    if (this->m_cstring){
        cout << "delete [] 释放旧的字符串 = " << this->m_cstring << endl;
        delete [] this->m_cstring;
        this->m_cstring = NULL;
    }
    //指向新的字符串
    if (cstring){
        this->m_cstring = new char[strlen(cstring)+1]{};
        strcpy(this->m_cstring, cstring);
        cout << "new [] 指向新的字符串 = " << cstring <<  endl;
    }
    return *this;
}

String &String::operator=(const String &string){
//    return operator=(string.m_cstring);
    return *this = string.m_cstring;
}

ostream &operator<<(ostream &cout,const String &string){
    if (!string.m_cstring) return cout;
    return cout << string.m_cstring;
}
#ifndef String_hpp
#define String_hpp

#include <stdio.h>
#include <iostream>

using namespace::std;

class String {
    friend ostream &operator<<(ostream &,const String &);
private:
    //C语言字符串
    char *m_cstring;
    
    String &assign(const char *cstring);
    
public:
    //单参数构造函数
    String(const char *cstring);
    
    //拷贝构造函数
    String(const String &string);
    
    ~String();
    
    //C语言字符串
    String &operator=(const char *cstring);
    //String字符串
    String &operator=(const String &string);
};

#endif /* String_hpp */
//  String.cpp
//  C++35_运算符重载(String)
//
//  Created by ljj on 8/15/21.
//

#include "String.hpp"

String::String(const char *cstring){
    assign(cstring);
}

String::String(const String &string){
    assign(string.m_cstring);
}

String::~String(){
    assign(NULL);
}

String &String::operator=(const String &string){
    return assign(string.m_cstring);
}

String &String::assign(const char *cstring){
    //指向相同的堆空间 直接返回
    if (this->m_cstring == cstring) return *this;
    //释放旧的字符串
    if (this->m_cstring){
        cout << "delete [] 释放旧的字符串 = " << this->m_cstring << endl;
        delete [] this->m_cstring;
        this->m_cstring = NULL;
    }
    //指向新的字符串
    if (cstring){
        this->m_cstring = new char[strlen(cstring)+1]{};
        strcpy(this->m_cstring, cstring);
        cout << "new [] 指向新的字符串 = " << cstring <<  endl;
    }
    return *this;
}

ostream &operator<<(ostream &cout,const String &string){
    if (!string.m_cstring) return cout;
    return cout << string.m_cstring;
}
//  String.hpp
//  C++35_运算符重载(String)
//
//  Created by ljj on 8/15/21.
//

#ifndef String_hpp
#define String_hpp

#include <stdio.h>
#include <iostream>

using namespace::std;

class String {
    friend ostream &operator<<(ostream &,const String &);
private:
    //C语言字符串
    char *m_cstring = NULL;
    
    String &assign(const char *cstring);
    //C语言字符串拼接
    char* join(const char *cstring1,const char *cstring2);
    
public:
    //单参数构造函数 默认参数值为空
    String(const char *cstring = "");
    
    //拷贝构造函数
    String(const String &string);
    
    ~String();
    
    //C语言字符串
    String &operator=(const char *cstring);
    //String字符串
    String &operator=(const String &string);
    
    String operator+(const char *cstring);
    String operator+(const String &string);
    
    String &operator+=(const char *cstring);
    String &operator+=(const String &string);
    
    //返回指定位置的字符
    char operator[](size_t index);
    
    bool operator>(const char *cstring);
    bool operator>(const String &string);
};


#endif /* String_hpp */
//  String.cpp
//  C++35_运算符重载(String)
//
//  Created by ljj on 8/15/21.
//

#include "String.hpp"

String::String(const char *cstring){
    assign(cstring);
}

String::String(const String &string){
    assign(string.m_cstring);
}

String::~String(){
    assign(NULL);
}

String &String::operator=(const String &string){
    return assign(string.m_cstring);
}

String &String::assign(const char *cstring){
    //指向相同的堆空间 直接返回
    if (this->m_cstring == cstring) return *this;
    //释放旧的字符串
    if (this->m_cstring){
        cout << "delete [] 释放旧的字符串 = " << this->m_cstring << endl;
        delete [] this->m_cstring;
        this->m_cstring = NULL;
    }
    //指向新的字符串
    if (cstring){
        this->m_cstring = new char[strlen(cstring)+1]{};
        strcpy(this->m_cstring, cstring);
        cout << "new [] 指向新的字符串 = " << cstring <<  endl;
    }
    return *this;
}

char* String::join(const char *cstring1,const char *cstring2){
    if (!cstring1 || !cstring2) return NULL;
    
    char *newString = new char[strlen(cstring1) + strlen(cstring2) + 1]{};
    strcat(newString, cstring1);
    strcat(newString, cstring2);
    return newString;
}


String String::operator+(const char *cstring){
    String str;
    char *newString = join(this->m_cstring, cstring);
    if (newString){
        //回收str 之前的空的("")堆空间
        str.assign(NULL);
        
        str.m_cstring = newString;
    }
    return str;
}

String String::operator+(const String &string){
    return operator+(string.m_cstring);
}

String &String::operator+=(const char *cstring){
    char *newString = join(this->m_cstring, cstring);
    if (newString) {
        this->assign(NULL);
        this->m_cstring = newString;
    }
    //返回当前对象本身 给返回值引用
    return *this;
}

String &String::operator+=(const String &string){
    return operator+=(string.m_cstring);
}

char String::operator[](size_t index){
    if (index < 0 || !this->m_cstring) return '\0';
    if (index >= strlen(this->m_cstring)) return '\0';
    return this->m_cstring[index];
}

bool String::operator>(const char *cstring){
    if (!this->m_cstring || !cstring) return 0;
    return strcmp(this->m_cstring, cstring) > 0;
}

bool String::operator>(const String &string){
    return operator>(string.m_cstring);
}

ostream &operator<<(ostream &cout,const String &string){
    if (!string.m_cstring) return cout;
    return cout << string.m_cstring;
}

调用父类的运算符重载函数

//  main.cpp
//  C++35_运算符重载(String)
//
//  Created by ljj on 8/15/21.
//

#include <iostream>

using namespace::std;

class Person {
    int m_age;
public:
    Person &operator=(const Person &person){
        this->m_age = person.m_age;
        return *this;
    }
};

class Student : public Person {
    int m_score;
    
public:
    Student &operator=(const Student &student){
        //调用父类的运算符重载函数
        Person::operator=(student);
        this->m_score = student.m_score;
        return *this;
    }
};

int main(int argc, const char * argv[]) {
    
    return 0;
}
上一篇 下一篇

猜你喜欢

热点阅读