对象指针的向量,初始化
Vector of object pointers, initialisation
我对C++还不是很有经验,所以如果这是基本的东西,请耐心等待。
我在下面有一些类似的代码。 L
是一个抽象类(它有许多纯虚函数),A
、B
和C
都是从L
派生的正则类。这些可能有很多,它们都是不同的。
int main() {
// ...
std::vector<L*> ls(3) ;
ls[0] = new A ;
ls[1] = new B ;
ls[2] = new C ;
int i ;
for (i = 0 ; i < ls.size() ; i++) {
if (ls[i]->h()) {
// ...
}
}
// ...
}
它有效,但确实必须有更好的方法来初始化该向量。右?
向量在首次初始化后不应更改。但是,我想我不能让它恒定,因为各种对象本身可能会在内部发生变化。我在常规数组上选择一个向量,因为我不想手动跟踪它的长度(事实证明容易出错)。
理想情况下,我想将向量的定义和初始化从main
中提取出来,最好是到一个单独的文件中,然后我可以#include
。当我尝试编译器抱怨它"在'='令牌之前预期构造函数、析构函数或类型转换"时。所有类A
、B
和C
都有默认构造函数。
另外,我的印象是我必须手动delete
使用new
创建的任何内容,但它不会删除delete
或delete[]
ls
。如果我尝试delete ls;
编译器会抱怨"键入'类 std::vector<L*,std:::allocator><L*>>"参数给出给'删除',预期的指针"。
以上是否安全或会导致一些内存问题?
但是确实必须有更好的方法来初始化该向量。右?
我不这么认为,至少没有 C++0x。你更喜欢哪种方式?您的初始化代码完全没问题。
但是,我想我不能让它恒定,因为各种对象本身可能会在内部发生变化。
您仍然可以使向量本身const
,只有其成员类型不能是指向const
的指针。
我在常规数组上选择一个向量,因为我不想手动跟踪它的长度(事实证明容易出错)。
您不必跟踪常量数组中的长度:
L* ls[] = { new A, new B, new C };
// with <boost/range/size.hpp>
std::size_t num = boost::size(ls);
// without Boost, more error-prone
// std::size_t num = sizeof ls / sizeof ls[0];
通常你不需要大小,例如使用Boost.Range。
理想情况下,我想将向量的定义和初始化从 main 中提取出来,最好是拉到一个单独的文件中,然后我可以 #include。
这将违反单一定义规则。可以将声明放入头文件中,但定义必须放入源文件中。
另外,我的印象是我必须手动删除使用 new 创建的任何内容,但它不会通过删除或删除 [] 删除 ls 来删除 ls。
你的印象是正确的,但你没有用new
创建ls
,只有它的元素。使用向量后,您必须delete
其每个元素,但不是向量本身。
保存多态指针的 STL 容器的推荐替代方法是 Boost 指针容器库。
您确实必须在您创建的对象上使用删除。 您是在向量而不是对象上调用删除。 像这样:
for(size_t i = 0; i < ls.size(); i++){
delete ls[i];
}
对于您的构造问题,您可以将它们包装到一个函数中,并将该函数放在它自己的头文件中。 您必须确保包含所有相关的类头文件。
void init_vector(std::vector<LS*> & v){
ls[0] = new A ;
ls[1] = new B ;
ls[2] = new C ;
}
如果C++11是可以接受的,那么你最好使用std::array
而不是std::vector
:
std::array<L *, 3> = {new A(), new B(), new C()};
由于您知道编译时的大小,因此我建议使用 array
而不是 vector
。使用类模板array
而不是 C 样式数组可以为您提供标准容器接口的好处,就像 vector
一样。也就是说,您可以在数组上调用size()
并获取迭代器等。
为了确保你不要忘记delete
对象,我建议使用智能指针:
#include <boost/array.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
boost::array<boost::shared_ptr<L>, 3> ls = { {
boost::make_shared<A>(),
boost::make_shared<B>(),
boost::make_shared<C>(),
} };
现代编译器在标准库中发布自己的array
和shared_ptr
版本:
#include <array>
#include <memory>
std::array<std::shared_ptr<L>, 3> ls = { {
std::make_shared<A>(),
std::make_shared<B>(),
std::make_shared<C>(),
} };
请注意,从技术上讲,最外层的大括号是不需要的,但是将它们排除在外可能会产生编译器警告,至少在我的编译器上是这样。
理想情况下,我想将向量的定义和初始化从
main
中提取出来,最好是到一个单独的文件中,然后我可以#include
在这种情况下,您需要一个带有声明的头文件和一个定义为 ls
的实现文件:
// file ls.h
#ifndef LS_H
#define LS_H
#include <boost/array.hpp>
#include <boost/shared_ptr.hpp>
extern boost::array<boost::shared_ptr<L>, 3> ls;
#endif
// file ls.cpp
#include "ls.h"
#include <boost/make_shared.hpp>
boost::array<boost::shared_ptr<L>, 3> ls = { {
boost::make_shared<A>(),
boost::make_shared<B>(),
boost::make_shared<C>(),
} };
- 如何使用C++初始化向量;脚本化值不是数组、指针或矢量错误
- 在C++中初始化向量映射的最有效方法
- 我使用向量来创建类对象列表.初始化向量时如何使用参数调用构造函数?
- 用向量的向量元素初始化向量的空向量
- 初始化向量数组,其中每个向量的大小为 0
- 如何初始化向量<unordered_map<*,*>>
- 如何在元组初始化向量中删除样板?
- C++ 通过函数声明后初始化向量
- 特征::向量;在函数中使用 Eigen::Matrix3f 的值初始化向量,大于 4 个条目
- 使用所述填充构造函数初始化向量中的向量
- 制作可用于初始化向量的迭代器
- 如何使用sregex_token_iterator对象初始化向量
- 用空向量 c++ 的 M 元素初始化向量
- 用reference_wrapper本地初始化向量
- 将向量元素与字符串元素进行比较,而不初始化向量
- 使用 reference_wrappers 初始化向量
- 从不同类型的容器的迭代器初始化向量
- 在具有容量/调整大小的类中初始化向量
- 在头文件中声明和初始化向量
- 错误:调用'begin(long double [nPoints])'没有匹配函数;使用硬编码的 int 与整数变量初始化向量