C++特殊成员

简介: 📖作者介绍:22级树莓人(计算机专业),热爱编程<目前在c++阶段>——目标Windows,MySQL,Qt,数据结构与算法,Linux,多线程,会持续分享学习成果和小项目的📖作者主页:热爱编程的小K📖专栏链接:c++🎉欢迎各位→点赞👏 + 收藏💞 + 留言🔔​💬总结:希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🐾————————————————版权声明:本文为CSDN博主「热爱编程的小K」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/qq_72157449

b001fac979f74f1e92c787b295bdf9af.png

64d6e6bef6354148a237a70ea5222e0c.png

目录

一、const

1.const数据成员

  • 不能被修改,const数据成员
  • 初始化必须采用初始化参数列表

2.const成员函数

  • 写法上比较特殊的写法,const修饰函数,写在函数后面
  • const函数和普通函数可以共存
  • 普通对象优先调用普通函数
  • 常对象只能调用常成员函数
  • const函数不能修改数据成员

3.const对象

常对象只能调用常成员函数

#include<iostream>

#include<string>

using namespace std;

class MM

{

public:

MM(string name,int age):m_name(name)

{

 m_age=age;

 //m_name=name;                 //错误,const数据只能使用初始化参数列表初始化

}

void print()

{

 //m_name="fsdaf";              //错误,const数据不能被修改

 cout<<m_age<<"\t"<<m_name<<endl;

}

protected:

const string m_name;

int m_age;

};

class GG

{

public:

GG(int num,string sex):num(num),sex(sex){}

void print() const

{

 //nume=45;       //错误,常成员函数不能修改数据成员

 cout<<"常对象只能调用常成员函数"<<"\t"<<num<<"\t"<<sex<<endl;

}

void print()

{

 cout<<"普通对象优先调用普通函数"<<endl;

}

void printD()

{

 cout<<"!"<<endl;

}

protected:

int num;

string sex;

};

int main()

{

const GG x(15,"boy");

x.print();

//x.printD();         //错误,常对象只能调用常成员函数

GG y(19,"girl");

y.print();

return 0;

}

二、this指针

1. 用来在类中表示对象本身
2. 避免名字同名问题,用来区分参数和数据成员

#include<iostream>

#include<string>

using namespace std;

class MM

{

public:

MM(int age,string name)

{

 this->age=age;

 this->name=name;

 //this=nullptr;     //错误

}

void print(){cout<<this->name<<"\t"<<this->age<<endl;}

//函数返回对象

MM GetMM()

{

 return *this;  

}

//函数返回对象指针

MM* Getpoint()

{

 return this;  

}

protected:

int age;

string name;

};

int main()

{

MM mm(15,"dhaskf");

mm.print(); //this表示mm的地址

//语法上ok。没有实际含义

mm.GetMM().GetMM().GetMM().GetMM().GetMM().GetMM().GetMM().GetMM().GetMM().GetMM();

mm.Getpoint()->Getpoint()->Getpoint();

return 0;

}

三、静态成员

static修饰数据或者函数,叫做静态成员,静态成员不属于对象,属于类,所有对象的公有的。

静态依旧受权限限定

静态成员的访问

通过对象访问

直接类名限定访问

静态数据必须在类外做初始化,类初始化不需要static修饰

静态成员函数

不能直接访问非静态数据成员,必须要通过对象访问

静态成员函数中没有this指针(不能使用this指针)

#include<iostream>

#include<string>

using namespace std;

class MM

{

public:

MM(string name) :name(name)

{

 count++;

 cout << "!!!!" << endl;

}

protected:

string name;

public:

static int count;

};

int MM::count = 0;

class GG

{

public:

GG(string name) :name(name) {}

static void printData()

{

 //this->name="fsdfs";   //错误写法,静态成员函数没有this指针

 cout << "静态成员函数" << endl;

 //cout<<name<<endl;    //错误写法,静态成员函数不能直接访问非静态成员数据成员

 cout << count << endl;   //静态成员可以直接访问;静态数据成员

}

//静态数据成员的间接访问------>1.传入参数,2.在该函数里面创建对象

static void print(GG& girl)

{

 cout << girl.count << "\t" << girl.name << endl;

 GG xx("mm");

 cout << xx.count << "\t" << endl;

}

protected:

string name;

static int count;

};

int GG::count = 0;

int main()

{

//静态数据是所有对象公有的

MM mm("king");

cout << MM::count << endl;

cout << mm.count << endl;

MM xx("KK");

cout << MM::count << endl;

cout << xx.count << endl;

cout << MM::count << endl;

cout << mm.count << endl;

GG gg("king");

gg.print(gg);

gg.printData();

GG::printData();

GG::print(gg);

}

四、c++友元

c++友元代表一种关系,一种无视类的权限限定的关系,c++友元关系用friend关键字描述

  • 友元函数
  • 友元类
  • 注:友元关系只是提供一个场所,赋予对象具有无视权限的功能,打破类的封装性

1.友元函数

  • 普通函数成为友元
  • 另一个类的成员函数成为友元函数
  • 友元函数不属于类,就是一个外部函数

#include<iostream>

#include<string>

using namespace std;

class MM

{

public:

void print(){cout<<"Hello,word!"<<endl;}

friend void see();

friend void king(MM& mm);

protected:

string name="dsafsa";

private:

int age=99;

};

//类外实现不需要friend,不需要类名限定

void see()

{

MM xx;

xx.print();

cout<<xx.name<<"\t"<<xx.age<<endl;

}

void king(MM& mm)

{

mm.print();

cout<<mm.name<<"\t"<<mm.age;

}

int main()

{

see();

MM girl;

king(girl);

return 0;

}

2.友元类

#include<iostream>

#include<string>

using namespace std;

class A

{

friend class B;

public:

void print()

{

 cout<<name<<"无视权限"<<endl;

}

protected:

string name="king";

};

class B

{

public:

void print()

{

 cout<<a.name<<endl;

 a.print();

}

protected:

A a;

};

//互为友元

class MM

{

friend class GG;

public:

void PrintMM();

protected:

string name="dsff";

};

class GG

{

friend class MM;

public:

void PrintGG()

{

 MM object;

 cout<<object.name;

}

protected:

int gg=20;

};

void MM::PrintMM()

{

GG xg;

cout<<xg.gg;

}

int main()

{

A a;

B b;

b.print();

 

GG kl;

kl.PrintGG();

MM sg;

sg.PrintMM();

}

五、有头链表

#include<iostream>

#include<new>

using namespace std;

class Node

{

public:

/*void initNode(int data)

{

 m_data = data;

 next = nullptr;

}*/

Node(int data):m_data(data),next(nullptr){}

Node():next(nullptr){}

void printNode()

{

 cout << m_data << " ";

}

Node*& getNext() { return next; }

protected:

int m_data;

Node* next;

};

class List  

{

public:

/*void createHead()     //创建表头

{

 headNode = new Node;     //new一个表头节点

 headNode->getNext() = nullptr;  //把表头节点next指针置为空

  }*/

List():headNode(new Node){}

void insertNode(int data)    //插入节点

{

 Node* newNode = new Node(data);    //new一个新节点

 //newNode->initNode(data);     //初始化新节点数据

 newNode->getNext() = headNode->getNext();  

 headNode->getNext() = newNode;

}

void printList()

{

 Node* pmove = headNode->getNext();  //从第二个节点开始

 while( pmove != NULL )        

 {

  pmove->printNode();     //调用打印节点函数

  pmove = pmove->getNext();      //指针往下走

 }

 cout << endl;

}

protected:

Node* headNode;

};

int main()

{

List list;

//list.createHead();

for (int i = 0; i < 10; i++)

{

 list.insertNode(i + 2);

}

list.printList();

return 0;

}

六、无头链表

#include<iostream>

#include<new>

using namespace std;

struct Node  

{

int data;

Node* next;

void print()

{

 cout << data << " ";

}

/*void initNode(int Data)

{

 data = Data;

 next = nullptr;

  }*/

Node(int data):data(data),next(nullptr){}

};

class List  

{

public:

void push_front(int data);         //头插法

void push_back(int data);          //尾插法

void pop_front();                  //头部删除

void pop_back();                   //尾部删除

 

//万金油函数

int size() { return m_size; }

bool empty() { return m_size == 0; }

 

//访问头结点和尾结点数据

int front() { return frontNode->data; }

int tail() { return tailNode->data; }

void print();

protected:

//万精油属性

int m_size = 0;     //记录当前链表中的节点个数

Node* frontNode = nullptr;    //起标识作用,第一个节点

Node* tailNode = nullptr;     //最后一个节点

};

void List::push_front(int data)

{

Node* newNode = new Node(data);

//newNode->initNode(data);

if ( m_size==0 )       //只有一个节点的时候,头就是尾,尾就是头

{

 tailNode = newNode;

}

else

{

 newNode->next = frontNode;

}

frontNode = newNode;

m_size++;

}

void List::push_back(int data)

{

Node* newNode = new Node(data);

//newNode->initNode(data);

if(m_size==0)

{

 frontNode = newNode;

}

else

{

 tailNode->next = newNode;

}

tailNode = newNode;

m_size++;

}

void List::pop_front()

{

if ( empty())

 return;

Node* nextNode = frontNode->next;

delete frontNode;

if (nextNode == nullptr)

{

 tailNode = nullptr;

}

frontNode = nextNode;

m_size--;

}

void List::pop_back(){

if (empty())

{

 return;

}

else if ( frontNode == tailNode )

{

 pop_front();

}

else

{

 Node* curNode = frontNode;

 while (curNode->next != tailNode)

 {

  curNode = curNode->next;

 }

 delete tailNode;

 curNode->next = nullptr;

 tailNode = curNode;

 m_size--;

}

}

void List::print()

{

Node* curNode = frontNode;

while (curNode != NULL)  

{

 curNode->print();

 curNode = curNode->next;

}

cout << endl;

}

int main()  

{

List list;

for (int i = 0; i < 10; i++)

{

 list.push_front(i);

}

list.print();

list.push_back(99);

list.print();

list.pop_front();

list.print();

list.pop_back();

list.print();

//边打印边删

while (!list.empty())

{

 cout << list.front() << " ";

 list.pop_front();

}

//了解,这些函数都有现成的

//std::list<int> mylist;

//mylist.push_back(45);

//mylist.pop_back();

return 0;

}

七、单指针无头链表

#include<iostream>

#include<new>

using namespace std;

struct Node

{

int data;

Node* next;

//Node(int data):data(data),next(nullptr){cout<<"king";}

Node(int data,Node* next):data(data),next(next){}

};

class List

{

public:

void push_front(int data)

{

 headNode=new Node(data,headNode);

 cursize++;

}

void printList()const

{

 Node* pmove=headNode;

 while(pmove!=nullptr)

 {

  cout<<pmove->data<<" ";

  pmove=pmove->next;

 }

 cout<<endl;

}

~List()

{

 Node* pmove=headNode;

 while(pmove!=nullptr)

 {

  Node* nextNode=pmove->next;

  delete pmove;

  pmove=nextNode;

 }

 cursize=0;

}

protected:

Node* headNode=nullptr;

int cursize=0;

};

int main()

{

List* p=new List;

for(int i=0;i<=8;i++)

{

 p->push_front(i);

}

p->printList();

return 0;

}

版权声明:本文为CSDN博主「热爱编程的小K」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qq_72157449/article/details/128632931

相关文章
|
2月前
|
C++
C++程序中对象成员的引用
C++程序中对象成员的引用
30 2
|
2月前
|
存储 Serverless 数据安全/隐私保护
C++ 类的成员函数和数据成员的技术性探讨
C++ 类的成员函数和数据成员的技术性探讨
33 0
|
1月前
|
数据采集 存储 编译器
this指针如何使C++成员指针可调用
本文介绍了C++中的this指针,它是一个隐藏的指针,用于在成员函数中访问对象实例的成员。文章通过代码示例阐述了this指针的工作原理,以及如何使用指向成员变量和成员函数的指针。此外,还提供了一个多线程爬虫示例,展示this指针如何使成员指针在对象实例上调用,同时利用代理IP和多线程提升爬取效率。
this指针如何使C++成员指针可调用
|
11天前
|
存储 C++
【C++】string类的使用③(非成员函数重载Non-member function overloads)
这篇文章探讨了C++中`std::string`的`replace`和`swap`函数以及非成员函数重载。`replace`提供了多种方式替换字符串中的部分内容,包括使用字符串、子串、字符、字符数组和填充字符。`swap`函数用于交换两个`string`对象的内容,成员函数版本效率更高。非成员函数重载包括`operator+`实现字符串连接,关系运算符(如`==`, `&lt;`等)用于比较字符串,以及`swap`非成员函数。此外,还介绍了`getline`函数,用于按指定分隔符从输入流中读取字符串。文章强调了非成员函数在特定情况下的作用,并给出了多个示例代码。
|
25天前
|
安全 数据安全/隐私保护 C++
C++一分钟之-成员访问控制:public, private, protected
【6月更文挑战第20天】C++的成员访问控制涉及`public`、`private`和`protected`,影响类成员的可见性和可访问性。`public`成员对外公开,用于接口;`private`成员仅限类内部,保护数据安全;`protected`成员在派生类中可访问。常见问题包括不恰当的访问级别选择、继承中的访问权限误解及过度使用友元。通过示例展示了如何在派生类中访问`protected`成员。正确使用访问修饰符能确保代码的封装性、安全性和可维护性。
43 4
|
1月前
|
编译器 C++ 存储
【C++语言】类和对象--默认成员函数 (中)
【C++语言】类和对象--默认成员函数 (中)
【C++语言】类和对象--默认成员函数 (中)
|
11天前
|
C++
【C++】string类的使用④(常量成员Member constants)
C++ `std::string` 的 `find_first_of`, `find_last_of`, `find_first_not_of`, `find_last_not_of` 函数分别用于从不同方向查找目标字符或子串。它们都返回匹配位置,未找到则返回 `npos`。`substr` 用于提取子字符串,`compare` 则提供更灵活的字符串比较。`npos` 是一个表示最大值的常量,用于标记未找到匹配的情况。示例代码展示了这些函数的实际应用,如替换元音、分割路径、查找非字母字符等。
|
11天前
|
编译器 C++
【C++】类和对象⑤(static成员 | 友元 | 内部类 | 匿名对象)
📚 C++ 知识点概览:探索类的`static`成员、友元及应用🔍。
|
20天前
|
编译器 C++
【C++】:const成员,取地址及const取地址操作符重载
【C++】:const成员,取地址及const取地址操作符重载
11 0
|
2月前
|
编译器 C语言 C++
从C语言到C++⑦(第二章_类和对象_下篇)初始化列表+explicit+static成员+友元+内部类+匿名对象(上)
从C语言到C++⑦(第二章_类和对象_下篇)初始化列表+explicit+static成员+友元+内部类+匿名对象
19 1