以下内容与this直接相关。我想要的是能够一次调用并且只激活一个类,以节省内存,还因为我打算稍后添加一个GUI,所以我可以通过一个来调用类下拉菜单(例如)。
我尝试制作作品,这就是出来的结果:
#include <iostream>
class Power
{
private:
double m_x;
public:
Power() {std::cout<<"Power\n";}
Power(double x): m_x {x} {std::cout<<"Power("<<x<<")\n";}
~Power() {std::cout<<"~Power\n";}
const double getX() const { return m_x; }
};
class Scanner
{
private:
Power m_power;
public:
Scanner() {std::cout<<"Scanner\n";}
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<<"Printer\n";}
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<<"Copier\n";}
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
可以用{{1}打印出来}和3.14
。如果我有超过2个类(我这样做),我可以调用每个类,每个类都会占用内存。那不是我想要的东西。
如何一次只调用一个班级而不必调用额外的重置或删除?我想为它添加另一个类,请参阅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
(除了他们自己的)。我不认为将公共变量移动到每个类是非常有效的,因为它们只会膨胀代码,而且,据我所知,“如果你可以使用存储类而不是一遍又一遍地重复相同的变量,用它“(不是我的话,这是真的吗?)。然后,我希望能够实例化这些类,但一次只有一个活动,以节省内存。
作为一个例子,假设一个类生成1mil值的数组,然后另一个生成1mil不同的值,依此类推。想象一下,在内存中使用该数组的次数与实例化的类一样多。我不希望这样。 Power
的目的是一次只调用一个类(基于条件)。任务完成?打电话给另一个,但忘记之前做过的任何其他事情,重新开始。所有这些只能通过一个小部件调用,例如从列表中选择,单击&amp; go,稍后将添加。
这是一个愚蠢的错误,我忘了在复制粘贴后删除Copier
。我现在也尝试了代码(使用public ...
),它编译,但仍然不起作用,Copier
保持为空,即使有两个m_x
和{{的非常难看的解决方案1}}指针作为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<<"Garage\n";}
virtual ~Garage() {std::cout<<"~Garage\n";}
};
class Audi: virtual public Garage
{
public:
Audi() {std::cout<<"Audi\n";}
void f(const double &x) { m_x=x; std::cout<<"Audi::f("<<x<<")\n";}
};
class Bmw: virtual public Garage
{
public:
Bmw() {std::cout<<"Bmw\n";}
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<<"Driver\n";}
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
(这就是为什么代码有点不同)。< / p>
我想指出的是,只要达到我的目的,我就不会保留这些代码或任何其他代码,我愿意改变和适应。但由于我是一个初学者,我不能制作太多的组合,所以我只留下了我试图让自己理解的任何结果。上面的程序,就像运行时一样,提供我想要的东西,甚至可以制作一个循环,这将让我在GUI中更容易使用它,以后。这些名称在组成中最有意义,m_x
有一个 m_y
,这就是我尝试过的,但我无法获得我的意思通缉。因此,即使这使用了继承并且Garage
是-a Bmw
也没有意义,我保留了名称来建议我的初始试用组合。我发布这个的主要原因是为了展示我希望该程序做什么。 Audi
中发生的事情将在GUI中使用,我在考虑Qt,因为我希望在所有3个主要操作系统上运行。因此,有可能一次调用一辆汽车,使用它,并且能够存储以前的信息,而不会在内存中存在过时的对象,只有Garage
* nr_of_cars,这将使它更容易使用。
答案 0 :(得分:1)
这是一种方法。
{ // 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
答案 1 :(得分:0)
使用一些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));
}
也许你真正想要的是tagged union。关注rule of five。请参阅this获取灵感。