Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何删除类的一部分?_C++_Oop - Fatal编程技术网

C++ 如何删除类的一部分?

C++ 如何删除类的一部分?,c++,oop,C++,Oop,问题很简单。我有一个可以按以下方式组织的类: class-MyClass{ 结构A{ // ... }; 结构B{ // ... }; }; 问题是:MyClass::B中的信息在经过一段时间的预计算后是无用的,而MyClass::A永远不能删除(程序可能会运行数天)MyClass::B包含大量信息。我想摆脱MyClass::B,同时保持MyClass::A在相同的内存位置 是否可以在不太修改数据结构的情况下执行此操作,并且不必向MyClass::A添加任何其他内容(特别是指向MyClass:

问题很简单。我有一个可以按以下方式组织的类:

class-MyClass{
结构A{
// ...
};
结构B{
// ...
};
};
问题是:
MyClass::B
中的信息在经过一段时间的预计算后是无用的,而
MyClass::A
永远不能删除(程序可能会运行数天)
MyClass::B
包含大量信息。我想摆脱
MyClass::B
,同时保持
MyClass::A
在相同的内存位置

是否可以在不太修改数据结构的情况下执行此操作,并且不必向
MyClass::A
添加任何其他内容(特别是指向
MyClass::B
)的指针)?如果是这样,正确的实施方式是什么?考虑到程序必须尽可能地提高内存效率(让我们把它发挥到极致)。顺便说一句,我使用C++14


(还有一个额外的问题:可以从
MyClass
?)中删除与
MyClass::B
相对应的块)

首先或者全部,这是一个类声明。不能删除类声明的一部分。你可能有更像这样的东西:

// The exact place of the declaration doesn't matter actually
class A {...}; 
class B {...};

class C {
    A a;
    B b;
}; 
只需将其更改为使用指针(在今天使用智能指针,如):

C类{
A A;
std::唯一的ptr b;
void完成需要的任务b(){
b、 reset();//调用b::~b()并释放内存。
}
}; 

好的,让我们详细说明一下我写的内容:“要么B的生命与MyClass的生命相关联,要么它是独立的。在后一种情况下,您必须以某种方式跟踪它”

把问题的背景放回去:

  • 经过一段时间的预计算后,MyClass::B是无用的
  • 决不能删除MyClass::A
就是你想以某种方式跟踪它。怎么用?嗯,这取决于生命时间的规则

  • 如果B有时可能存在,有时不依赖于难以控制(或完全不可知)的情况,那么只有一个解决方案,即在B无用时将其指针设置为
    nullptr
    ,在B有用时动态分配
但在这里,我们有更多的知识:B先存在,然后变得无用,永远如此。换句话说,在用于创建A的一些初始构建步骤之后,您不需要B

有一种模式正是这样做的:即。它的目的是封装一个复杂的构建操作,可能跟踪某个状态,直到它构建了某个对象,此时它就变得无用并可以被销毁

class ABuilder
{
public:
    setSomeInfo(int);
    doSomeComputation(......);
    // etc

    A get();    /// finalize building of A

private:
    int someInfo_ = 0;
};

// somewhere else
auto b = ABuilder();
b.setSomeInfo(42);
b.doSomeComputation(......);

auto a = b.get();
// b is no longer used past that point
// delete it if it was allocated dynamically
// or let it go out of scope if it was automatic
根据您的示例,它的映射有点像这样:

// The exact place of the declaration doesn't matter actually
class A {...}; 
class B {...};

class C {
    A a;
    B b;
}; 
  • A
    仍然是
    A
  • B
    a文件
  • MyClass
    不需要

如果您提供了实际的类名和用途,那么将更容易使示例变得有意义;)

在任何情况下,指针都很可能是你渴望的钥匙。在任何情况下,也需要将
B
MyClass
分开。如果单独存储
B
,并反转指针的方向,则可以避免MyClass中的指针(请参见问题和其他答案的注释):

class MyClass
{
    struct A { };
    A a;
};

class Wrapper
{
    struct B { };

    MyClass* mc;
    B b;
};
现在,在初始化过程中,您需要为每个
MyClass
创建一个
包装器,很可能包含在两个不同的数组中:

MyClass items[NUMBER_OF_ITEMS]; // global array?

Wrapper* wrappers = new Wrapper[NUMBER_OF_ITEMS];
// assign each item to its corresponding wrapper

// use the wrappers for initialisation

delete[] wrappers;

现在剩下的只是一个指针,如果它是单独初始化例程中的局部变量,您甚至可以去掉它。

MyClass::B
是一种类型。类型不消耗内存,变量消耗内存。但您的示例中没有变量。也许您希望将
std::unique_ptr b
作为数据成员,而不是
b
。将b因子去掉,并将指针指向it@Galik,我意识到了这一点,并将其从评论中删除。但是,如果
B
在堆上分配了一些固定的存储量,
std::optional
可能会很有用。为什么“将
MyClass::A
保持在相同的内存位置”很重要?你有
MyClass
对象数组吗?@Evg因为我有指向
A
的指针,谢谢你的回答@churill。然而,这正是我试图避免的(对不起,在你写答案的时候,我编辑了这篇文章来澄清这一点)。我想使用
A
而不必处理这个额外的指针。@VictorMartin为什么没有指针?只要对象存在,任何子对象(如
b
)都将占用对象的内存。对象的大小固定在C++中,所以,唯一的选择是使用指针。那么,指针指向“代码> B<代码>有什么问题?A不受这些更改的影响。@VictorMartin,因为我个人觉得它有点丑陋和不必要-抱歉,但这是一个非常错误的不使用某些东西的原因。指针在C++中无处不在,在处理动态数据时,你无法避免它们。至于您的问题,要么
B
的子对象将在相应的
MyClass
对象的整个生命周期中占用其空间,要么您将使用指针。你不能两者兼得。@VictorMartin让我们简单地说:要么B的生命与MyClass的生命相关联,要么它是独立的。在后一种情况下,您必须以某种方式跟踪它。