面向對象主要包括三大類:封裝,繼承,多態
1.類和對象
c++認為,萬物皆為對象,對象上有其屬性和行為
人可以作為對象,屬性有姓名、年齡、身高、體重...,行為有走、跑、跳、吃飯、唱歌...
車也可以作為對象,屬性有輪胎、方向盤、車燈...,行為有載人、放音樂、放空調...
具有相同性質的==對象==,我們可以抽象稱為==類==,人屬于人類,車屬于車類
對象是類的實例。
2.封裝
1.封裝的意義
1. 將屬性和行為統一為一個整體,表現為生活中的事物
2. 將屬性和行為加以權限控制
封裝意義一:
將屬性和行為統一為一個整體,表現為生活中的事物
語法: class 類名{ 訪問權限: 屬性 / 行為 };
示例1:設計一個圓類,求圓的周長
沒學封裝之前,用C語言實現:
#include<stdio.h>
double circleCaculate(double r)
{return 3.14*r*r;
}
int main(int argc, char const *argv[])
{double r = 1.2;double area = circleCaculate(r);return 0;
}
在這里面r相當于屬性,circleCaculate()相當于行為,在C語言里屬性和行為是分開的;
用封裝實現
#include<iostream>
using namespace std;
class Circle
{
public: //protected private 權限int r; // 屬性double circleCaculate() // 行為{return 3.14*r*r;}
};
int main(int argc, char const *argv[])
{Circle c; // Circle是類 c是對象c.r = 1.2;area = c.circleCaculate();cout<<area<<endl;return 0;
}
類不占內存,但可以用sizeof計算出它的大小,對象才占內存。
示例2:設計一個學生類,屬性有姓名和學號,可以給姓名和學號賦值,可以顯示學生的姓名和學
//學生類
class Student {public:void setName(string name) {m_name = name;}void setID(int id) {m_id = id;}void showStudent() {cout << "name:" << m_name << " ID:" << m_id << endl;}public:string m_name;int m_id;};
int main() {Student stu;stu.setName("德瑪西亞");stu.setID(250);stu.showStudent();system("pause");return 0;
}
封裝意義二:
可以把屬性和行為放在不同的權限下,加以控制
訪問權限有三種:
1. public 公共權限
2. protected 保護權限
3. private 私有權限
//三種權限
//公共權限 public 類內可以訪問 類外可以訪問
//保護權限 protected 類內可以訪問 類外不可以訪問
//私有權限 private 類內可以訪問 類外不可以訪問
class Person
{//姓名 公共權限public:string m_Name;//汽車 保護權限protected:string m_Car;//銀行卡密碼 私有權限private:int m_Password;public:void func(){m_Name = "張三";m_Car = "拖拉機";m_Password = 123456;}
};
int main() {Person p;p.m_Name = "李四";//p.m_Car = "奔馳"; //保護權限類外訪問不到//p.m_Password = 123; //私有權限類外訪問不到system("pause");return 0;
}
//三種權限
//公共權限 public 類內可以訪問 類外可以訪問
//保護權限 protected 類內可以訪問 類外不可以訪問
//私有權限 private 類內可以訪問 類外不可以訪問
2.struct和class區別
在C++中 struct和class唯一的區別就在于 默認的訪問權限不同
區別:
struct 默認權限為公共
class 默認權限為私有,如果想訪問必須明確為public權限
class C1
{int m_A; //默認是私有權限
};
struct C2
{int m_A; //默認是公共權限
};
int main() {C1 c1;c1.m_A = 10; //錯誤,訪問權限是私有C2 c2;c2.m_A = 10; //正確,訪問權限是公共system("pause");return 0;
}
3.成員屬性要設置為私有
優點1:將所有成員屬性設置為私有,可以自己控制讀寫權限
優點2:對于寫權限,我們可以檢測數據的有效性
class Person {public://姓名設置可讀可寫void setName(string name) {m_Name = name;}string getName(){return m_Name;}//獲取年齡int getAge() {return m_Age;}//設置年齡void setAge(int age) {if (age < 0 || age > 150) {cout << "你個老妖精!" << endl;return;}m_Age = age;}//情人設置為只寫void setLover(string lover) {m_Lover = lover;}private:string m_Name; //可讀可寫 姓名int m_Age; //只讀 年齡string m_Lover; //只寫 情人
};
int main() {Person p;//姓名設置p.setName("張三");cout << "姓名: " << p.getName() << endl;//年齡設置p.setAge(50);cout << "年齡: " << p.getAge() << endl;//情人設置p.setLover("蒼井");//cout << "情人: " << p.m_Lover << endl; //只寫屬性,不可以讀取system("pause");return 0;
}
4.類的聲明和定義
可以類的聲明,和類的定義分離,在.h文件中聲明,在.cpp文件中定義
用客戶端的代碼來舉例:
頭文件:
#ifndef CLIENT_H
#define CLIENT_H
#include<iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include<netinet/in.h>
#include<unistd.h>
#include <arpa/inet.h>
#include<cstdio>
#include<cstring>
#include<cstdlib>
class Tcpclient
{private:int sockfd;//臨時struct sockaddr_in server_addr;public:Tcpclient(const std::string& serverIp,short port);~Tcpclient();bool ConnectToServer();int SendToServer(const std::string& data);int RecvFromServer(char* buffer,int buffersize);};
#endif
client.cpp
#include<iostream>
#include"client.hpp"
using namespace std;Tcpclient::Tcpclient(const std::string& serverIp,short port){ //創建socketsockfd=socket(AF_INET,SOCK_STREAM,0);//ipv4 tcpif(sockfd<0){cerr<<"Failed to create socket"<<endl;sockfd=-1;return;}//服務的地址:IP 端口號server_addr.sin_family=AF_INET;server_addr.sin_port=htons(port);server_addr.sin_addr.s_addr=inet_addr(serverIp.c_str());
}
Tcpclient::~Tcpclient(){close(sockfd);
}
bool Tcpclient::ConnectToServer(){if(connect(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr))<0){cerr<<"connect err"<<endl;return false;}cout<<"connect success!"<<endl;return true;
}
//
int Tcpclient::SendToServer(const std::string& data){return send(sockfd,data.c_str(),data.size(),0);
}
int Tcpclient::RecvFromServer(char* buffer,int buffersize){return recv(sockfd,buffer,buffersize,0);
}
main.cpp
#include"client.hpp"
using namespace std;
int main(int argc, char const *argv[])
{char buffer[1024]={0};Tcpclient tcp1("0.0.0.0",8082);tcp1.ConnectToServer();tcp1.SendToServer("hello");tcp1.RecvFromServer(buffer,sizeof(buffer));cout<<buffer<<endl;return 0;
}