一次只实例化一组类中的一个类,以节省内存
Instantiate only one class at a time, out of a group of classes, to save memory
以下内容与此直接相关。我想要的是一次只能调用和激活一个类,以节省内存,但也因为我计划在以后添加GUI,所以我将能够通过下拉菜单(例如)调用类。
我试着做合成,结果是这样的:
#include <iostream>
class Power
{
private:
double m_x;
public:
Power() {std::cout<<"Powern";}
Power(double x): m_x {x} {std::cout<<"Power("<<x<<")n";}
~Power() {std::cout<<"~Powern";}
const double getX() const { return m_x; }
};
class Scanner
{
private:
Power m_power;
public:
Scanner() {std::cout<<"Scannern";}
Scanner(const Power &p): m_power {p} {std::cout<<"Scanner("<<&p<<")n";}
void print() {std::cout<<"x="<<m_power.getX()<<'n';}
};
class Printer
{
private:
Power m_power;
public:
Printer() {std::cout<<"Printern";}
Printer(const Power &p): m_power {p} {std::cout<<"Printer("<<&p<<")n";}
void print() {std::cout<<"x="<<m_power.getX()<<'n';}
};
class Copier // if Copier is to be used for "unification", will "public" be needed?
{
private:
Scanner *m_s;
Printer *m_p;
int m_i;
public:
Copier() {std::cout<<"Copiern";}
Copier(const Power &p, int i): m_i {i}
{
if (i)
m_s = new Scanner(p);
else
m_p = new Printer(p);
std::cout<<"Copier("<<&p<<","<<i<<")n";
}
void print() { std::cout << (m_i ? m_s->getX() : m_p->getX()) << 'n'; }
};
int main(int argc, char *argv[])
{
Scanner *s {new Scanner(Power(2.3))};
s->print();
Printer *p {new Printer(Power(3.14))};
p->print();
s->print(); // here, both *s and *p exist, both use memory
// this comes after considering adding class Copier
Copier *c {new Copier(Power(1.618), 0)};
c->print();
c = new Copier(Power(2.718), 1);
c->print();
return 0;
}
暂时忽略Copier
。实际上,我可以使用它,结果是这样的:
Power(2.3)
Scanner(0x7ffc80d98c10)
~Power
x=2.3
Power(3.14)
Printer(0x7ffc80d98c20)
~Power
x=3.14
x=2.3
现在的(主要)问题是内存中有多个对象,有*s
和*p
,正如您可以看到的,x
可以用3.14
和2.3
打印出来。如果我有两个以上的类(我确实有),我可以调用每个类,每个类都会占用内存。那不是我想要的。
如何一次只调用一个类而不必调用额外的重置或删除?我想为它添加另一个类,参见Copier
。但是我不能使用std::unique_ptr
,在代码中的解决方案是,不仅非常丑陋,但甚至不工作。而且它疯狂地调用构造函数
我尝试在一个简单的函数中使用std::unique_ptr
, std::make_unique
(需要c++14
,我宁愿保持一些更大的安全边际,但我也可以忍受它)。它也不起作用,因为它指向Power
(如果我调用z->print()
,它会说'class Power' has no member 'print'
):
std::unique_ptr<Power> call(const Power &p, const int &i)
{
if (i)
return std::make_unique<Printer>(p);
else
return std::make_unique<Scanner>(p);
}
我不知道怎么做这个。简而言之,Scanner
、Printer
和其他存在的类都是专用的类,它们只执行一项任务,其计算方式是唯一的,并且它们都使用Power
中的一些通用变量(除了它们自己的变量之外)。我不认为将公共变量移动到每个类是非常有效的,因为它们只会使代码膨胀,而且,正如我所理解的那样,"如果您可以使用存储类而不是一遍又一遍地重复相同的变量,就使用它"(不是我的话,这是真的吗?)然后,我希望能够实例化这些类,但一次只有一个活动,以节省内存。
Copier
的目的是一次只调用一个类(基于条件)。完成工作吗?打电话给另一个,但是忘记之前做过的任何事情,重新开始。所有这些都可以通过一个小部件调用,例如select from list, click&go,这将在稍后添加。
这是一个愚蠢的错误,我忘记删除public ...
后复制粘贴。我现在也尝试了代码(与Copier
),它编译,但仍然不起作用,m_x
保持空,即使有两个Scanner
和Printer
指针作为Copier
内部的成员变量的非常丑陋的解决方案。
好吧,经过一些尝试,我不能做我想要的,所以我想回到我最初的想法,即使这意味着继承。所以我写了这段代码,在这里我改变了名字,使它更有意义(?):
#include <iostream>
class Garage
{
protected:
double m_x; // gas, tires, etc, that all cars use, reside in the Garage
public:
Garage() {std::cout<<"Garagen";}
virtual ~Garage() {std::cout<<"~Garagen";}
};
class Audi: virtual public Garage
{
public:
Audi() {std::cout<<"Audin";}
void f(const double &x) { m_x=x; std::cout<<"Audi::f("<<x<<")n";}
};
class Bmw: virtual public Garage
{
public:
Bmw() {std::cout<<"Bmwn";}
void f(const double &x) { m_x=x; std::cout<<"Bmw::f("<<x<<")n";}
};
class Driver: public Audi, public Bmw
{
private:
double m_y; // report of driving, based on m_x
public:
Driver() {std::cout<<"Drivern";}
Driver(const double &x, int i)
{
if (i)
Bmw::f(x);
else
Audi::f(x);
m_y = -m_x;
std::cout<<"Driver("<<x<<","<<i<<")n";
}
void print() { std::cout << "x=" << m_x << ", y=" << m_y << 'n'; }
};
int main(int argc, char *argv[])
{
Driver *d {new Driver(1.618, 0)};
d->print();
d = new Driver(0.618, 1);
d->print();
// even iteration works now
delete d;
d = nullptr; // to be sure it's dead(?)
for (int i=0; i<2; ++i)
{
d = new Driver(3.14, i);
d->print();
}
return 0;
}
现在,这工作,但我有一种感觉,我创造了一个新的记录,在糟糕的代码示例。请不要为此抨击我,而是指出所有的错误,或者你会如何做才能达到同样的结果。尽管如此,即使它看起来像我想要的那样工作,它仍然调用所有分支上的所有构造函数,而不是只调用所需的构造函数。我意识到(我的道歉)我忘了说Driver
,在这里,也负责进一步使用m_x
,因为它的m_y
(这就是为什么代码有点不同)。
我想指出的是,我并不固定保持这段代码,或任何其他,我愿意改变和适应,只要我达到我的目的。但由于我是初学者,我不能做太多的组合,所以我只能把我得到的结果呈现出来,试图让别人理解我。上面的程序,就像它一样,在运行时,给出了我想要的,甚至有可能产生一个循环,这将使我在GUI中更容易使用它,稍后。这些名称,就其本身而言,在组合中最有意义,Garage
有-a Bmw
,这就是我所尝试的,但我无法获得我想要的。因此,即使这使用了继承,并且Audi
是-a Garage
没有意义,我保留了这些名称,以表明我对组合的初步尝试。我发布这篇文章的主要原因是为了展示我想要这个程序做什么。在main()
中发生的事情将在GUI中使用,我正在考虑Qt,因为我希望它在所有3个主要操作系统上运行。因此,有可能一次调用一辆车,使用它,也能够存储以前的信息,而不会在内存中有过时的对象,只有m_x
*nr_of_cars,将使它更容易使用。
这是一种方法。
{ // scope begins
Printer p; // note, no pointers
p.print();
} // scope ends, p is gone
这里有一个对象出现,做了一件事,然后消失。
这是另一个
boost::variant<Printer,Scaner,Copier> psc(Printer());
psc.get<Printer>().print();
psc = Scaner(); // the printer is gone
使用std::unique_ptr构造函数:
std::unique_ptr<Power>
call(const Power &p, const int &i) {
if (i)
return std::unique_ptr<Power>(new Printer(p));
else
return std::unique_ptr<Power>(new Scanner(p));
}
也许你真正想要的是一个带标签的联合。遵循"五"原则。
- 重新定位图像时如何前进到下一个内存块
- 当分配一个字符串值并稍后通过分配另一个值进行更改时C++如何管理内存?
- 给定一个指向堆分配内存的指针,智能指针实现如何为其找到合适的释放函数?
- 是否可以通过每次在内存中仅保存一个平铺来处理完整的平铺 tiff 图像?
- 如何使用带有矢量的 winapi 读取进程内存从另一个进程读取缓冲区?
- 是否可以使用分配器对象来释放另一个分配器分配的内存?
- C++,一个内存块与多个内存块
- 使用一个内存集数组和单个堆栈在 O(n) 中查找数组的下一个更大元素
- 从一个内存的一个块创建许多eigen :: vectorxd
- 如何使用任意数量的(编译时间确定的)容器创建一个内存池
- 未知错误,调试器只给我一个内存地址
- 你能给我一个内存泄漏的真实工作示例吗?
- 如何知道两个C字符串是否指向一个内存块
- 设计一个内存覆盖检测工具
- Getline返回一个内存地址
- 如何获得一个内存区域的保护标志,标志是PROT_READ /PROT_EXEC在mprotect
- c++又是一个内存泄漏问题
- 为什么我在这里得到一个内存相关的错误
- 我可以为多个向量使用一个内存池吗
- 一个内存高效的SHA1实现