1.class与struct有什么区别
C语言的struct与C++的class的区别:struct只是作为一种复杂数据类型定义,不能用于面向对象编程。
C++中的struct和class的区别:对于成员访问权限以及继承方式,class中默认的是private的,而struct中则是public的。class还可以用于表示类模板,struct 则不行。
2.静态成员变量的使用
//2.静态成员变量的使用
#include<iostream>
using namespace std;
class Myclass
{
public:
Myclass(int a, int b, int c);
void GetNumber();
void GetSum();
private:
int A;
int B;
int C;
int Num;
static int Sum; //定义Sum为静态类型,它为Myclass类所有,被Myclass类的所有对象所共享
};
int Myclass::Sum = 0;
Myclass::Myclass(int a, int b, int c)
{
A = a;
B = b;
C = c;
Num = A + B + C;
Sum = A + B + C;
}
void Myclass::GetNumber()
{
cout << "Number = " << Num << endl;
}
void Myclass::GetSum()
{
cout << "Sum = " << Sum << endl;
}
void main()
{
Myclass M(3, 7, 10), N(14, 9, 11); //定义两个类对象
M.GetNumber(); //20 Num成员为普通类型,它为Myclass类的对象所有,
N.GetNumber();//34 因此,每次打印出来的值不一样
M.GetSum(); //34 Sum成员为静态类型,它为Myclass类所有,被Myclass类的所有对象
N.GetSum(); //34 所共享,因此,两个打印出来的值是相同的。
}
Number = 20
Number = 34
Sum = 34
Sum = 34
3.与全局对象相比,使用静态数据成员有什么优势
(1)静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其他全局名字冲突的可能性。
(2)使用静态数据成员可以隐藏信息。因为静态数据成员可以是private成员,而全局对象不能。
4.静态成员函数的错误使用
//4.静态成员函数的错误使用
#include<iostream>
using namespace std;
//class test
//{
//public:
// static int i; //i为静态成员变量
// int j;
// test(int a):i(1),j(a){} //错误,不能初始化i,静态成员变量应该在类定义外面初始化
// void func1();
// static void func2();
//};
//void test::func1(){cout << i << ", " << j << endl;}
//void test::func2() { cout << i << ", " << j << endl; }//错误。静态成员函数和静态成员变量一样,不属于类的对象
// //因此它不含this指针,也就无法调用类的非静态成员j
//改正:
class test
{
public:
static int i;
int j;
//test(int a) :i(1), j(a) {}
test(int a):j(a){}
void func1();
static void func2();
};
int test::i = 1; //在类外初始化静态成员变量
void test::func1() { cout << i << ", " << j << endl; }
void test::func2() { cout << i << /*", "<<j<<*/endl; } //注释掉对j的调用
int main()
{
test t(2);
t.func1();
t.func2();
return 0;
}
1, 2
1
5.C++中的空类默认会产生哪些类成员函数
C++的空类中,默认会产生默认析构函数、复制构造函数、析构函数、赋值函数以及取值运算。
6.构造函数和析构函数是否可以被重载
构造函数可以被重载,因为构造函数可以有多个,且可以带参数。
析构函数不可以被重载,因此析构函数只能有一个,且不能带参数。
7.析构函数的执行顺序
//7.析构函数的执行顺序
#include<iostream>
using namespace std;
class A
{
private:
int a;
public:
A(int aa) { a = aa; }
~A()
{
cout << "Destructor A!" <<a<< endl;
}
};
class B:public A
{
private :
int b;
public:
B(int aa = 0, int bb = 0) :A(aa), b(bb) {};
~B()
{
cout << "Destructor B!" << b << endl;
}
};
void main()
{ //析构函数的执行顺序与构造函数的执行顺序相反。
B obj1(5), obj2(6, 7); //定义了两个类B的对象,它们的基类是A,当main()函数退出的时候会发生析构,因为obj1比obj2
//先声明,所有obj2先析构。它们的析构顺序是首先执行B的析构函数,然后执行A的析构函数
return;
}
Destructor B!7
Destructor A!6
Destructor B!0
Destructor A!5
8.编写类String的构造函数、析构函数和赋值函数
//8.编写类String的构造函数、析构函数和赋值函数
#include<iostream>
using namespace std;
class String
{
public:
String(const char *str = NULL); //普通构造函数
String(const String &other); //复制构造函数
~String(void); //析构函数
String & operator =(const String &other); //赋值函数
private:
char *m_String; //私有成员,保存字符串
};
String::~String(void) //析构函数
{
cout << "Destructing" << endl;
if (m_String != NULL)
{
delete [] m_String;
m_String = NULL;
}
}
String::String(const char* str) //普通构造函数
{
cout << "Construcing" << endl;
if (str == NULL)
{
m_String = new char[1]; //分配一个字节
*m_String = '\0'; //将之赋值为字符串结束符
}
else
{
m_String = new char[strlen(str) + 1]; //分配空间容纳str内容
strcpy_s(m_String,strlen(str)+1, str); //复制str到私有成员
}
}
String::String(const String &other) //复制构造函数
{
cout << "Constructing Copy" << endl;
m_String = new char[strlen(other.m_String) + 1]; //分配空间容纳other.m_String的内容
strcpy_s(m_String, strlen(other.m_String) + 1, other.m_String);
}
String & String::operator=(const String &other) //赋值函数
{
cout << "Operate = Function" << endl;
if (this == &other) //如果对象和other是同一个对象
{
return *this;
}
delete[] m_String; //先释放当前对象的堆内存
m_String = new char[strlen(other.m_String) + 1]; //然后分配足够大小长度的堆内存复制字符串
strcpy_s(m_String,strlen(other.m_String)+1, other.m_String); //执行复制
return *this;
}
int main()
{
String a("hello"); //执行普通构造函数
String b("world"); //执行普通构造函数
String c(a); //执行复制构造函数
c = b; //调用赋值函数
return 0;
}
Construcing
Construcing
Constructing Copy
Operate = Function
Destructing
Destructing
Destructing