C++的哲学就是把所有东西都封装一下,提供访问控制(安全控制),提供更多的方法和功能。这种封装也可以称为抽象,通过更高一层的抽象来实现隐藏和安全。
0 结构体封装和控制:访问控制+函数指针+构造析构
1 原生指针封装和定制:迭代器、智能指针
2 C风格字符串封装和定制:string类
3 函数封装和定制:函数对象
4 原生数组封装和控制:array类、vector类
5 栈封装和控制:stack类
6 浮点数也可以封装和定制,可以定义一下浮点数比较方式
7 整数也可以封装和定制,可以判断一下是否上溢和下溢
8 封装malloc+构造函数:new
9 FILE封装一下:stream类
参考:
参考:
C++|从使用指针的迭代操作到使用模板技术的指针类(迭代器)
C++|类封装如何提升安全和可维护性,以智能指针封装裸指针为例
C++|引用计数与shared_ptr智能指针(以实现String类为例)
#include
#include
class String
{
public:
String(const char* cstr = 0);
String(const String& str);
String& operator=(const String& str);
~String(){
delete[] m_data;
}
char* get_c_str() const{
return m_data;
}
private: char* m_data;
};
String::String(const char* cstr)
{
if(cstr)
{
m_data = new char[strlen(cstr)+1];
strcpy(m_data,cstr);
}
else {
m_data = new char[1];
*m_data = '\0';
}
}
String::String(const String& str)
{
m_data = new char[strlen(str.m_data)+1];
strcpy(m_data,str.m_data);
}
String& String::operator=(const String& str)
{
if(this == &str)
return *this;
delete[] m_data;
m_data = new char[strlen(str.m_data)+1];
strcpy(m_data,str.m_data);
return *this;
}
int main()
{
String str("abc");
String str2(str);
String str3 = str2;
printf("%s
",str3.get_c_str());
return 0;
} #include
class Fib {
public:
Fib() : a0_(1), a1_(1) {}
int operator()() {
int temp = a0_;
a0_ = a1_;
a1_ = temp + a0_;
return temp;
}
private:
int a0_, a1_;
};
int main()
{
Fib fib;
for(int i=1;i<50;i++)
printf("%2d %d
",i,fib());
getchar();
} #ifndef INTARRAY_H
#define INTARRAY_H
#include // for assert()
class IntArray
{
private:
int m_length{};
int* m_data{};
public:
IntArray() = default;
IntArray(int length):
m_length{ length }
{
assert(length >= 0);
if (length > 0)
m_data = new int[length]{};
}
IntArray(std::initializer_list list) // allow IntArray to be initialized via list initialization
: IntArray(static_cast(list.size())) // use delegating constructor to set up initial array
{
// Now initialize our array from the list
int count{ 0 };
for (auto element : list)
{
m_data[count] = element;
++count;
}
}
~IntArray()
{
delete[] m_data;
// we don't need to set m_data to null or m_length to 0 here, since the object will be destroyed immediately after this function anyway
}
void erase()
{
delete[] m_data;
// We need to make sure we set m_data to nullptr here, otherwise it will
// be left pointing at deallocated memory!
m_data = nullptr;
m_length = 0;
}
int& operator[](int index)
{
assert(index >= 0 && index < m_length);
return m_data[index];
}
// reallocate resizes the array. Any existing elements will be destroyed. This function operates quickly.
void reallocate(int newLength)
{
// First we delete any existing elements
erase();
// If our array is going to be empty now, return here
if (newLength <= 0)
return;
// Then we have to allocate new elements
m_data = new int[newLength];
m_length = newLength;
}
// resize resizes the array. Any existing elements will be kept. This function operates slowly.
void resize(int newLength)
{
// if the array is already the right length, we're done
if (newLength == m_length)
return;
// If we are resizing to an empty array, do that and return
if (newLength <= 0)
{
erase();
return;
}
// Now we can assume newLength is at least 1 element. This algorithm
// works as follows: First we are going to allocate a new array. Then we
// are going to copy elements from the existing array to the new array.
// Once that is done, we can destroy the old array, and make m_data
// point to the new array.
// First we have to allocate a new array
int* data{ new int[newLength] };
// Then we have to figure out how many elements to copy from the existing
// array to the new array. We want to copy as many elements as there are
// in the smaller of the two arrays.
if (m_length > 0)
{
int elementsToCopy{ (newLength > m_length) ? m_length : newLength };
// Now copy the elements one by one
for (int index{ 0 }; index < elementsToCopy; ++index)
data[index] = m_data[index];
}
// Now we can delete the old array because we don't need it any more
delete[] m_data;
// And use the new array instead! Note that this simply makes m_data point
// to the same address as the new array we dynamically allocated. Because
// data was dynamically allocated, it won't be destroyed when it goes out of scope.
m_data = data;
m_length = newLength;
}
void insertBefore(int value, int index)
{
// Sanity check our index value
assert(index >= 0 && index <= m_length);
// First create a new array one element larger than the old array
int* data{ new int[m_length+1] };
// Copy all of the elements up to the index
for (int before{ 0 }; before < index; ++before)
data[before] = m_data[before];
// Insert our new element into the new array
data[index] = value;
// Copy all of the values after the inserted element
for (int after{ index }; after < m_length; ++after)
data[after+1] = m_data[after];
// Finally, delete the old array, and use the new array instead
delete[] m_data;
m_data = data;
++m_length;
}
void remove(int index)
{
// Sanity check our index value
assert(index >= 0 && index < m_length);
// If we're removing the last element in the array, we can just erase the array and return early
if (m_length == 1)
{
erase();
return;
}
// First create a new array one element smaller than the old array
int* data{ new int[m_length-1] };
// Copy all of the elements up to the index
for (int before{ 0 }; before < index; ++before)
data[before] = m_data[before];
// Copy all of the values after the removed element
for (int after{ index+1 }; after < m_length; ++after)
data[after-1] = m_data[after];
// Finally, delete the old array, and use the new array instead
delete[] m_data;
m_data = data;
--m_length;
}
// A couple of additional functions just for convenience
void insertAtBeginning(int value) { insertBefore(value, 0); }
void insertAtEnd(int value) { insertBefore(value, m_length); }
int getLength() const { return m_length; }
};
#endif
#include
#include "IntArray.h"
int main()
{
// Declare an array with 10 elements
IntArray array(10);
// Fill the array with numbers 1 through 10
for (int i{ 0 }; i<10; ++i)
array[i] = i+1;
// Resize the array to 8 elements
array.resize(8);
// Insert the number 20 before element with index 5
array.insertBefore(20, 5);
// Remove the element with index 3
array.remove(3);
// Add 30 and 40 to the end and beginning
array.insertAtEnd(30);
array.insertAtBeginning(40);
// Print out all the numbers
for (int i{ 0 }; i #include
#include
#include
#include
#include
using namespace std;
template
class Stack {
private:
vector elems; // elements
public:
void push(T const&); // push element
void pop(); // pop element
T top() const; // return top element
bool empty() const { // return true if empty.
return elems.empty();
}
};
template
void Stack::push (T const& elem) {
// append copy of passed element
elems.push_back(elem);
}
template
void Stack::pop () {
if (elems.empty()) {
throw out_of_range("Stack<>::pop(): empty stack");
}
// remove last element
elems.pop_back();
}
template
T Stack::top () const {
if (elems.empty()) {
throw out_of_range("Stack<>::top(): empty stack");
}
// return copy of last element
return elems.back();
}
int main() {
try {
Stack intStack; // stack of ints
Stack stringStack; // stack of strings
// manipulate int stack
intStack.push(7);
cout << intStack.top() < ref
C++|包装裸指针、裸数组、字符串成智能指针、array类和string类
-End-
| 留言与评论(共有 0 条评论) “” |