c++ 类和动态内存分配

静态类成员函数

可以将函数成员声明为静态的,但如果函数定义时独立的,则不能包含关键字static例如:

class T
{
public:
	static int test();
};
 int T::test() ///这里不能是static int T::test()
{
	cout << "yes";
}

其次静态成员函数不与特定的对象相关联,因此只能使用静态数据成员。

mystring 类

#pragma once
#ifndef STRING_H_
#define STRING_H_
#include<iostream>
using namespace std;
#include<cstring>
class String
{
private:
	char* cp;
	int len;
	static int num_string;
	static const int CINLIM = 60;
public:
	String();
	String(const char* p);
	String(const String &);
	~String();
	int length()const
	{
		return len;
	}
	String& operator=(const String&);
	String& operator=(const char*);
	char& operator[](int i);
	const char& operator[](int i)const;///如果定义的是const String anser("hello world")则cout<<anser[0]会报错
	friend bool operator<(const String& st, const String& st2);
	friend bool operator > (const String& st, const String& st2);
	friend bool operator ==(const String& st, const String& st2);
	friend ostream& operator<<(ostream& os, const String& st);
	friend istream& operator>>(istream& is, String& st);
	static int HowMany();
};
#endif
#include"String.h"
int String::num_string = 0;///在类的声明外来初始化静态类成员,不能使用static
int String::HowMany()
{
	return num_string;
}
String::String(const char* s)
{
	len = strlen(s);
	cp = new char[len + 1];
	strcpy(cp, s);
	num_string++;
}
String::String()
{
	len = 0;
	cp = new char[1];
	cp[0] = '0';
	num_string++;
}
String::String(const String&st)
{
	len = st.len;
	cp = new char[len + 1];
	strcpy(cp, st.cp);
	num_string++;
}
String::~String()
{
	delete[]cp;
	--num_string;
}
String& String::operator=(const String& st)
{
	if (this == &st)
	{
		return *this;
	}
	delete[]cp;
	len = st.len;
	cp = new char[len + 1];
	strcpy(cp, st.cp);
	return *this;
}
String& String::operator=(const char* s)
{
	delete[]cp;
	len = strlen(s);
	cp = new char[len + 1];
	strcpy(cp, s);
	return *this;
}
char& String::operator[](int i)
{
	return cp[i];
}
const char& String::operator[](int i)const
{
	return cp[i];
}
bool operator>(const String& st, const String& st2)
{
	return strcmp(st.cp, st2.cp) > 0;
}
bool operator<(const String& st, const String& st2)
{
	return st2 > st;
}
bool operator==(const String& st, const String& st2)
{
	return strcmp(st.cp, st2.cp) == 0;
}
ostream& operator<<(ostream& os, const String& st)
{
	os << st.cp;
	return os;
}
istream& operator>>(istream& is,String& st)
{
	char temp[String::CINLIM];
	is.get(temp, String::CINLIM);
	if (is)
	{
		st = temp;
	}
	while (is && is.get() != '\n')
		continue;
	return is;
}
#include<iostream>
#include"String.h"
const int ArSize = 10;
const int MaxLen = 10;
int main()
{
	using namespace std;
	String name;
	cout << "Hi,What's your name?\n>>";
	cin >> name;
	cout << name << ",please enter up to" << ArSize
		<< " short sayings< empty line to quit>:\n";
	char temp[MaxLen];
	String saying[10];
	int i;
	for (i = 0; i < ArSize; ++i)
	{
		cout << i + 1 << ": ";
		cin.get(temp, MaxLen);
		while (cin && cin.get() != '\n')
			continue;
		if (!cin || temp[0] == '\0')
			break;
		else {
			saying[i] = temp;
		}
	}
	int total = i;
	if (total > 0)
	{
		cout << "Here are your sayings:\n";
		for (i = 0; i < total; ++i)
		{
			cout << saying[i][0] << ": " << saying[i] << endl;
		}
			int shortest = 0;
			int first = 0;
			for (i = 1; i < total; ++i)
			{
				if (saying[i].length() < saying[shortest].length())
					shortest = i;
				if (saying[i] < saying[first])
				{
					first = i;
				}
			}
			cout << "Shortest saying:\n" << saying[shortest] << endl;
			cout << "First saying:\n" << saying[first] << endl;
			cout << "This program used " << String::HowMany() << " String objects.Bye\n";
		}
	else
	{
		cout << "No input\n";
		return 0;
	}
}

operator<<(cout,s1)中的返回值必须是ostream&,而不能仅仅是ostream,如果是osream要调用ostream类的复制构造函数,而osream没有公有的复制构造函数。

使用new初始化对象

通常如果Class_name是类,value的类型为Type_name,则下面的语句:

Class_name * pclass=new Class_name(value);

将调用如下构造函数:

Class_name(Type_name);

这里可能还会有一些琐碎的转换,例如:

Class_name(const Type_name &);

下面的初始化方式将调用默认的构造函数:

Class_name * ptr=new Class_name;

定位new运算符

指针pc1指向的地址和buffer相同,但buffer是使用new[]初始化的,因此必须使用delete[]来释放buffer。即使buffer是使用new而不是new[]初始化的,delete pc1也将释放buffer而不是pc1。例如:

const int BUF = 512;
class T
{
private:
	string words;
public:
	T(const string& s = "hello world")
	{
		words = s;
	}
	~T()
	{
		cout << "no\n";
	}
};
int main()
{
	char* buffer = new char[BUF];
	T* pc1 = new(buffer)T;
	T* pc2 = new T("heap1");
	cout << (void*)buffer << " " << pc1 << endl << pc2 << endl;
	pc1->~T();
	delete[]buffer;
}

因此要显式得调用析构函数。
不能直接delete pc1,原因在于delete可和常规的new运算符配合使用,但不能与定位new运算符配合使用,如果直接delete pc1将会报错;

初始化列表

只有构造函数可以使用这种初始化列表语法。对于const类成员,必须使用这种语法,另外对于被声明为引用的类成员,也必须使用这种语法:

Class Agency{...}
class Agent
{
private:
Agency & belong;
};
Agent::Agent(Agency &a):belong(a){  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值