调用"new"以存储到shared_ptr的引用向量中

Calling 'new' to store into a referenced vector of shared_ptr's

本文关键字:ptr 引用 向量 shared new 存储 调用      更新时间:2023-10-16

我想改写这个问题,让它更清楚。 我有一种感觉,我的方法通常是错误的

它是否打破了依赖注入的意图,将共享指针向量的引用传递到构造函数中,目的是创建新的共享指针并将其推送到向量?

我知道不应该在对象中使用新命令。在这种情况下,它创建一个对象,但将其存储在外部。

有没有更好的方法来解决这个问题,以便"新"可以留在外面?

SpottingMarker.h

#ifndef SPOTTINGMARKER_H_INCLUDE
#define SPOTTINGMARKER_H_INCLUDE

class SpottingMarker
{
public:
    SpottingMarker() {;}
            ~SpottingMarker(){;}
    void blah();
    double mPosition;
    double mDuration;
    char* mDescription;
};
    #endif

发现标记.cpp

#include "SpottingMarker.h"
void blah() {;}

CsvSpottingNotes.h

#ifndef CSVSPOTTINGNOTES_H_INCLUDED
#define CSVSPOTTINGNOTES_H_INCLUDED

#include "SpottingMarker.h"
#include <boost/shared_ptr.hpp>
#include <vector>
typedef boost::shared_ptr<SpottingMarker> spottingMarker_ptr;
class CsvSpottingNotes
{
public:
    CsvSpottingNotes(const char* filename, std::vector<spottingMarker_ptr> &SpottingMarkerSet);
    ~CsvSpottingNotes(){;}
    const char* mFilename;
    const char field_terminator;
    const char line_terminator;
    const char enclosure_char;
};
    #endif

CsvSpottingNotes.cpp

#include "CsvSpottingNotes.h"
#include "SpottingMarker.h"
#include <csv_parser/csv_parser.hpp>
#include <boost/shared_ptr.hpp>
CsvSpottingNotes::CsvSpottingNotes(const char* filename, std::vector<spottingMarker_ptr> &SpottingMarkerSet) :
field_terminator(','),
line_terminator('n'),
enclosure_char('"')
{
    spottingMarker_ptr aSpottingMarker(new SpottingMarker());
    SpottingMarkerSet.push_back(aSpottingMarker);
}

主.cpp

#include "CsvSpottingNotes.h"
#include "SpottingMarker.h"
#include <vector>
int main(int argc, char ** argv)
{
    typedef boost::shared_ptr<SpottingMarker> spottingMarker_ptr;
    const char* filename = "AT_92.csv";
    std::vector<spottingMarker_ptr> spottingMarkerSet;
    CsvSpottingNotes structure(filename, spottingMarkerSet);
}

首先,为了解决您的直接问题,如果我理解正确,您想知道是否可以 (1( 创建一个具有本地作用域的共享指针,(2( 将其推到对共享指针向量的引用的后面,以及 (3( 让指针引用与您创建它时相同的对象。 所有这些问题的答案都是肯定的,而且您几乎可以免费获得这种行为。 例如:

void push_shared_pointer(std::vector<boost::shared_ptr<int> > &vector) {
  boost::shared_ptr<int> int_ptr(new int(5));
  vector.push_back(int_ptr);
  *int_ptr = 6;
}
std::vector<boost::shared_ptr<int> > int_vector;
push_shared_pointer(int_vector);
std::cout << *int_vector.back( ) << std::endl;

这输出 6,因为在函数中,自从我们将共享指针推送到向量上后,我们使用本地共享指针来修改引用的 int。 由于矢量中的共享指针和本地共享指针引用相同的内存位置,因此两个共享指针都会更新。

至于代码的其余部分,有几点需要注意。 首先,正如其他人指出的那样,预处理器防护是一个问题。 其次,你没有在 SopttingMarker 中限定函数 blah(( 的作用域.cpp告诉编译它是 SpottingMarker 类中 blah 函数的实现。 其内容应为:

#include "SpottingMarker.h"
void SpottingMarker::blah() { }

此外,由于您在标头中指示要提供用户定义的默认构造函数,因此也应该在 SpottingMarker 中提供该构造函数.cpp。

SpottingMarker::SpottingMarker()
  : mPosition(0)
  , mDuration(0)
  , mDescription(NULL)
{ }

第三,由于您在 CsvSpottingNotes.h 中声明了一个析构函数,因此您应该在 CsvSpottingNotes.cpp 中定义它:

CsvSpottingNotes::~CsvSpottingNotes() {
  // implementation here
}

这些应该是您需要的所有定义,至少根据您的构建日志。

我要指出的最后一件事是,由于三个原因,它看起来不像您以传统方式使用依赖注入。 首先,通常,当您执行依赖关系注入时,您将对注入对象的引用存储在接收器对象中,以便接收器可以在其生存期内使用。 在这里,您将向量注入到 CsvSpottingNotes 中,但不在类中存储对它的引用;您只需将共享指针推到其上即可。

其次,根据我的经验,依赖注入用于行为抽象,即使用接口将接收方(客户端(对象的行为与注入对象的行为分开。 这允许您通过注入接口的不同实现来修改客户端的行为。 在这种情况下,您没有使用接口;std::vector 在编译时是一个完全限定的类型,CsvSpaottingMarker 不能与任何其他类型一起使用,因此没有理由使用依赖注入。 更好的解决方案是将向量存储为 CsvSpottingMarker 的成员。

第三,正如我之前所说,依赖注入主要用于行为抽象,即根据注入到客户端对象的接口的实现而使客户端对象的行为不同。 std::vector 类不是依赖注入的良好候选项,因为它不提供行为;相反,它只是保存状态。 通常,对象的状态应封装为对象类的成员,这是对将向量包含在 CsvSpottingMarker 类中的进一步支持。

希望对您有所帮助!