静态类成员函数
可以将函数成员声明为静态的,但如果函数定义时独立的,则不能包含关键字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){ }