c++ - 指向类类型数组和带有 new 的构造函数的指针
问题描述
所以我正在编写一个类模板,我的类包含一个指向包含类类型实例的数组的指针。我的问题是我班级的构造函数。在我的构造函数中使用 new 关键字时,它无法正常工作。问题是当我在构造函数中使用 new 时没有创建我的数组。(就像它总是一个空指针而不是一个包含 Node 类实例的数组)我还应该说没有任何错误。这是我的代码。
#include <iostream>
#include <cstddef>
template <typename V>
class Node {
private:
V _data;
unsigned short _size;
Node<V>* _children;
public:
Node();
Node(V);
Node(V, unsigned short);
Node(const Node&); // copy constructor
~Node();
};
template <typename V>
Node<V>::Node()
: _data(0), _size(0), _children(nullptr) {}
template <typename V>
Node<V>::Node(V data)
: _data(data), _size(0), _children(new Node<V>[_size]) {}
template <typename V>
Node<V>::Node(V data, unsigned short size)
: _data(data), _size(size), _children(new Node<V>[_size]) {}
template <typename V>
Node<V>::Node (const Node& other)
: _size(other._size), _data(other._data) {
_children = new Node<V>[_size];
for (unsigned short i = 0; i < _size; i++)
_children[i] = other._children[i];
}
template <typename V>
Node<V>::~Node() { delete[] _children; }
int main () {
Node<int> n1;
Node<char> n2('A');
Node<char> n3('B', 5);
return 0;
}
感谢高级。
解决方案
我已将您的代码复制到 Visual Studio 2017 CE 中,并将其放在它自己的头文件中。当我尝试从您的问题中编译代码时,Visual Studio 给了我这个编译器错误:
1>------ Build started: Project: StackOverflow, Configuration: Debug Win32 ------
1>main.cpp
1>c:\users\...\container.h(41): error C2039: '{dtor}': is not a member of 'Node<V>'
1>c:\users\...\container.h(41): error C2447: '{': missing function header (old-style formal list?)
1>Done building project "StackOverflow.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
为了修复这个编译器错误,我必须在类本身中添加declaration
你的。dtor
declaration
template <typename V>
class Node {
//... previous code
public:
~Node();
};
这使我能够编译、构建和运行代码,最终我得到了一个0
. 在我看来,从语法或编译的角度来看,这段代码没有任何其他问题,但这并不意味着在正确性、效率或内存泄漏、悬空指针等方面没有任何问题。 ..
编辑
在处理此代码一段时间后,我注意到您现有代码存在一些问题:
您声明了这两个构造函数:
Node(V); Node(V, unsigned short);
你让他们像这样定义:
template <typename V> Node<V>::Node(V data) : _data(data), _size(0), _children(new Node<V>[_size]) {} template <typename V> Node<V>::Node(V data, unsigned short size) : _data(data), _size(size), _children(new Node<V>[_size]) {}
两者之间的唯一区别是大小的大小0
,否则它们似乎做完全相同的事情。在第一种情况下,anint data[0]
给了你什么?或者array
with0
元素会给你什么?
另一个问题涉及成员变量的使用。您使用的前缀_
是糟糕的代码设计,因为它们是为语言和编译器或其他东西保留的。如果要区分成员变量和非成员变量。我喜欢改用后置修复_
。示例:int non_member_varaible;
和int member_variable_;
。
为了清理您的代码,我删除了多个或冗余构造函数的额外依赖项。我还将它们保存在类声明中,因为这是一个类模板。我声明dtor
为默认值。我还通过使用and删除了new
and的使用。我还添加了一些辅助功能来检索大小和数据。我也没有对复制构造函数做任何事情,并且完全省略了它,因为一旦你的类可以运行,这应该是微不足道的。delete
std::vector
std::shared_ptr
如果您在编译时确切地知道数组的大小,您可以交换std::vector
并std::array
稍微修改代码。如果您希望此类拥有对象的唯一所有权,您可以通过一些细微的修改来std::shared_ptr
替换。std::unique_ptr
出于演示目的,我选择std::vector<std::shared_ptr<Node>>
用作内部容器。
也不是尝试向构造函数添加多个节点;我删除了那个依赖,只是把它变成了一个允许你在运行时添加节点的函数。如果在实例化该类时需要向该类添加多个节点,那么我建议使用variadic template constructor
. 可变参数构造函数还可以让您能够将任何 Node 类型添加到容器中,只需对代码稍作修改。
这是我想出的:
容器2.h
#pragma once
#include <vector>
#include <memory>
template <typename V>
class Node {
private:
V data_;
std::vector<std::shared_ptr<Node>> children_;
public:
Node() : data_{ 0 } {}
explicit Node(V data) : data_{ data } {}
void add_node(V data) {
auto p = std::make_shared<Node<V>>(Node(data));
children_.push_back(p);
}
~Node() = default;
const size_t size() const { return children_.size(); }
const V data() const { return data_; }
// no bounds checking just for demonstration purposes.
const V data(unsigned index) { return children_[index]->data_; }
};
主文件
#include <iostream>
//#include "Container.h"
#include "container2.h"
int main() {
try {
Node<int> n1;
Node<char> n2('A');
Node<char> n3('B');
n3.add_node('C');
n3.add_node('E');
std::cout << n3.size() << '\n';
std::cout << n3.data(1) << '\n';
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
输出
2
E
并且代码以退出代码退出0
!
推荐阅读
- c++ - 选择排序 - 数组与向量
- node.js - 基于性能、稳定性和 ES8+ 支持的 Knex 与 mysql2
- java - 为什么 Spring Boot 验证不适用于控制器(@Size - 注释)?
- cobol - COBOL:如何关闭屏幕并返回终端
- javascript - 使用 customElements 在 javascript 中创建页面构建框架
- microsoft-graph-toolkit - IE 和 mgt-login 不兼容
- javascript - 根据列的值发送电子邮件?
- matlab - 无法在matlab中的条形图上方放置图像
- r - 通过扭曲参数空间处理 Nelder-Mead 优化中的框约束
- excel - 调试 MS Excel for Mac 中的兼容性问题