/*-------------------------------------初始化例子------------------------------------------*/
class Data
{
public:
Data(int data): m_iData(data){ cout << "Data::Data()" << endl; }
~Data(){ cout << "Data::~Data()" << endl; }
void setData(int data) { cout << "Data::setData" << endl; m_iData = data; }
int getData() { return m_iData; }
private:
int m_iData;
};
class TData
{
public:
TData(): m_cData(5){ cout << "TData::TData()" << endl; }
~TData(){ cout << "TData::~TData()" << endl; }
void printData() { cout << "data = " << m_cData.getData() << endl; }
private:
Data m_cData;
};
int main()
{
TData d1;
d1.printData();
return 0;
}
结果:
Data::Data()
TData::TData()
data = 5
TData::~TData()
Data::~Data()
注意:
如果Data类的构造函数是无参的,那么在TData类的构造函数初始化列表中无需初始化(不需要显式初始化)。
初始化
类指针是指向类的指针变量。在C++中,类指针可以用于动态创建对象、访问类的成员和调用类的成员函数。
类指针的声明方式与普通指针相同,只需在类型前面加上类名和*号,例如:
ClassName* ptr;
然后,可以使用new运算符为类指针动态分配内存并创建对象:
ptr = new ClassName;
接下来,可以使用箭头运算符(->)来访问类的成员变量和成员函数:
ptr->memberVariable;
ptr->memberFunction();
当不再需要对象时,应使用delete运算符释放内存:
delete ptr;
这样可以确保在对象不再使用时释放内存,避免内存泄漏。
类指针的使用可以实现动态的对象创建和管理,提供更灵活的编程方式。
class Data
{
public:
Data(){cout << "Data::Data()" << endl;}
~Data(){}
void setData(int data) { cout << "Data::setData" << endl; m_iData = data; }
int getData() { return m_iData; }
private:
int m_iData;
};
Data a; //实例化一个类对象a
a.setData(1);
// Data *b = new Data();
Data *b; //实例化一个类指针b
b = new Data();
b->setData(2);
这种方法比较便捷,省去了初始化的麻烦,且可以动态的创建对象,但是也会带来内存的使用问题。初学者推荐使用第一种方法。指针的使用,需要一定功底,如果使用不当,
会出现内存访问违规或者内存泄露问题。指针的深入理解,请参考《指针的深入理解,深刻掌握指针》。
特别说明:为了防止内存泄露,new了对象后,一定要delete这个对象。最容易出现内存泄露的就是频繁的new对象和delete对象,导致前一个指向的对象没有删除就new了一个新对象给指针,
最后之前的对象就无法使用,知道程序结束才能被释放,这就是内存泄露了。正确的代码写法如下:
-----------------代码-------------------------------
if(NULL != pA)//此处需要初始化时设置指针为空。
{
delete pA;
pA = new A;
} else {
pA = new A;
}
-----------------代码-------------------------------
直接定义即可。比如已有一个类class A, 再定义一个类class B,这样在B的定义中,就可以有一个A*类型的成员变量。
比如
class B
{
A * a;
};
这里的B::a就是一个A*类型的指针。
需要注意的是,要使用这种形式的定义,要么A的定义在B的上方,要么在B定义前加一个A类的声明。
如
class A;
class B
{
A * a;
};
类名 *指针名
;
如 在一个类中定义指向另外一个类的指针:
class A {
public:
A();
~A();
.....
B *pt; //这个就是你要的,直接定义就好,但是记得要包含类B 的头文件
}
追问
那如何给改指针分配动态内存?
追答
我是这么做的:
pt = new B;
这个是在A的构造函数
里面定义的,别忘记在A的析构函数里面: if (B) delete pt;
追问
thanks!如果b的构造函数有1个int型的参数,那就是pt = new B(5);对不对?那这个动态内存的分配能直接放在类里面吗?我试过不行啊,后来放到函数里面动态分配才行。为什么
追答
直接放到类里面肯定是不行的,因为类里面是不允许初始化的。
std::unique_ptr 是 C++ 标准库中的智能指针类,用于管理动态分配的对象。它提供了独占式拥有权,即在任何时候只能有一个 std::unique_ptr 拥有对对象的唯一所有权。当 std::unique_ptr 被销毁或重置时,它会自动删除所管理的对象,从而避免内存泄漏。
std::unique_ptr 的主要特点和用法如下:
独占式所有权:一个 std::unique_ptr 实例拥有对对象的唯一所有权,不能拷贝或共享所有权。这意味着只能有一个 std::unique_ptr 实例指向同一个对象,从而避免了资源的多重释放和访问冲突。
托管动态分配的对象:std::unique_ptr 主要用于托管通过 new 或 std::make_unique 动态分配的对象。它可以管理任何可删除的对象,包括基本类型、自定义类型和数组等。
自动释放资源:当 std::unique_ptr 被销毁或重置时,它会自动调用所管理对象的析构函数,并释放对象所占用的内存。这消除了手动管理资源释放的需求,提高了代码的可靠性和安全性。
移动语义:std::unique_ptr 支持移动语义,可以通过移动构造函数和移动赋值运算符将所有权从一个 std::unique_ptr 实例转移给另一个实例,从而避免不必要的对象拷贝和资源释放。
#include
#include
class UniquePtr {
public:
UniquePtr() { std::cout << "调用构造函数" << std::endl; }
~UniquePtr() { std::cout << "调用析构函数" << std::endl; }
void print() { std::cout << "调用print()函数" << std::endl; }
};
int main() {
std::unique_ptr ptr(new UniquePtr());
ptr->print();
return 0;
}
int main() {
std::unique_ptr ptr(new UniquePtr());
std::unique_ptr ptr1(ptr); //报错
std::unique_ptr ptr2 = ptr; //报错
return 0;
}
unique_ptr虽然没有拷贝和赋值操作,但却提供了一种移动机制来将指针的所有权从一个unique_ptr转移给另一个unique_ptr。如果需要转移所有权,可以使用std::move()函数。
int main() {
std::unique_ptr ptr(new UniquePtr());
std::unique_ptr ptr2 = std::move(ptr); //转移所有权
std::unique_ptr ptr3(std::move(ptr));
return 0;
}
#include
#include
class UniquePtr {
public:
UniquePtr() { std::cout << "调用构造函数" << std::endl; }
~UniquePtr() { std::cout << "调用析构函数" << std::endl; }
void print() { std::cout << "调用print()函数" << std::endl; }
};
std::unique_ptr return_unique_ptr() {
std::unique_ptr ptr(new UniquePtr());
return ptr;
}
int main() {
std::unique_ptr ptr = return_unique_ptr();
return 0;
}
https://www.cnblogs.com/vivian187/p/14812987.html
链接:https://blog.csdn.net/L1413999/article/details/132092160
https://blog.csdn.net/wang13342322203/article/details/80807053
https://blog.csdn.net/Mr_xiao_1/article/details/80219162
https://www.cnblogs.com/TechNomad/p/17484529.html