- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在练习在 C++ 中使用模板和类。我的目标是为双端队列编写一个模板类。它将具有“insert_head”、“insert_tail”、“remove_tail”和“remove head”的功能,以及使用“cout”打印的能力。此外,“=”运算符必须能够用于将类的一个实例复制到另一个实例。这是我当前的代码:
#ifndef DEQUE_H
#define DEQUE_H
template <typename T>
class Deque {
public:
Deque(int size = 0, int capacity = 1000) : size_(size), capacity_(capacity)
{}
Deque(Deque & d) : x_(d.x()), size_(d.size()), capacity_(d.capacity()) {}
std::ostream & operator<<(std::ostream & cout) {
cout << '[';
if (size_ > 0) {
for (int i = 0; i < (size_ - 1)* sizeof(T); i += sizeof(T)) {
std::cout << *(x_ + i) << ',';
}
cout << *(x_ + (size_ - 1)* sizeof(T));
}
cout << ']';
return cout;
}
Deque operator=(Deque d) {
Deque dq(d);
return dq;
}
void print_test() {
std::cout << '[';
if (size_ > 0) {
for (int i = 0; i < (size_ - 1)* sizeof(T); i += sizeof(T)) {
std::cout << *(x_ + i) << ',';
}
std::cout << *(x_ + (size_ - 1)* sizeof(T));
}
std::cout << ']';
}
int * x() {
return x_;
}
int size() {
return size_;
}
int capacity() {
return capacity_;
}
bool is_empty() {
return size_ == 0;
}
void insert_tail(T tail) {
if (size_ < capacity_) {
*(x_ + sizeof(T) * size_) = tail;
size_++;
} else {
// throw overflow
}
}
T remove_tail() {
if (size_ > 0) {
T ret = *(x_ + sizeof(T) * (size_ - 1));
std::cout << ret;
size_--;
return ret;
} else {
// throw underflow
}
}
void insert_head(T head) {
if (size_ > 0 && size_ < capacity_) {
for (int i = (size_ - 1) * sizeof(T); i < 0; i -= sizeof(T)) {
*(x_ + i + sizeof(T)) = *(x_ + i);
}
}
if (size_ < capacity_) {
*x_ = head;
size_++;
} else {
// throw overflow
}
}
T remove_head() {
if (size_ > 0) {
T ret = *x_;
for (int i = sizeof(T); i < size_* sizeof(T); i += sizeof(T)) {
*(x_ + i - sizeof(T)) = *(x_ + i);
}
size_--;
return ret;
} else {
// throw underflow
}
}
private:
T * x_;
int size_;
int capacity_;
};
#endif
这是我使用该类的测试代码:
#include <iostream>
#include "Deque.h"
int main(int argc, char const *argv[])
{
Deque< int > dq;
dq.insert_head(1);
// dq.insert_head(2); // adding head when not empty causes bug
dq.insert_tail(3);
dq.insert_tail(4);
dq.insert_tail(5);
dq.print_test(); std::cout << std::endl;
// std::cout << dq; // '<<' not overloaded properly'
std::cout << dq.remove_head() << " head removed\n";
// int x = dq.remove_head(); // seg faults when assigning returned value to a variable
dq.insert_tail(2);
dq.print_test();
std::cout << std::endl;
Deque< int > dq1(dq);
Deque< int > dq2;
// dq2 = dq1; // '=' not overloaded properly
return 0;
}
我的四个问题中的每一个都在我的测试文件中注释掉的代码行中,这里有进一步的解释:
当调用“dq.insert_head(2)”并且 dq 不为空(大小 > 0)时,我尝试将双端队列中的所有其他元素移动到一个位置,以便我可以在那里插入新值,有问题,元素没移过来。
"std::cout << dq"没有按应有的方式打印 dq。该代码与“print_test()”方法非常相似,但是当我运行该程序时,出现错误“运算符 << 不匹配”。这是因为它是模板类吗?还是我在做其他完全错误的事情?
当尝试从双端队列中删除头或尾时,我试图返回删除的值。在未注释掉的代码行中,返回值按原样打印,但以下代码行导致段错误。是不是因为我试图将模板 varabale 分配给整数变量?
我的最后一个问题是“=”运算符没有将类的一个实例复制到另一个实例。我的目标是创建该类的一个新实例,然后返回该实例(如您在“Deque operator=(Deque d)”中看到的那样),但这并没有像我希望的那样工作。使用模板类重载“=”函数的最佳方法是什么。
感谢您的帮助,非常感谢您对这些问题的回答。
最佳答案
你所有的功能都有问题:
Deque(int size = 0, int capacity = 1000) : size_(size), capacity_(capacity) {}
假设,你想要一个固定的容量,那么你的构造函数应该是:
Deque(int capacity = 1000)
: size_(0)
, x_(new T[capacity])
, capacity_(capacity)
{
}
即使那是一个简化版本,因为它会为所有可能效率低下并需要 T
的项目调用构造函数有一个可访问的默认构造函数。
现在是复制构造函数:
Deque
后崩溃。您已经完成复制,因为删除一个项目两次是未定义的行为。Deque(const Deque &other);
代码看起来类似于:
Deque(const Deque &other)
: capacity_(other.capacity_)
, x_(new T[other.capacity_])
, size_(other.size_)
{
for (int i = 0; i != size_; ++i)
{
x_[i] = other.x_[i];
}
}
对于 <<
,原型(prototype)应该是:
friend std::ostream & operator<<(std::ostream &cout, const T &data)
假设它在类内部声明为访问私有(private)字段。您需要传递运算符(operator)工作的数据。
对于赋值运算符,像这样的东西可以工作:
Deque& operator=(const Deque &other)
{
// Use swap idiom...
Deque tmp(other);
// Swap pointers so old x_ get destroyed...
T *old_x = x_;
x_ = tmp.x_;
tmp.x_ = old_x;
// Usually one would use std::swap.
// Here as tmp get destroyed, it is not strictly to swap capacity_ and size_.
capacity_ = tmp.capacity_;
size_ = tmp.size_;
}
现在为 x()
功能:- 如果你做一个队列,你可能不想公开数据所以这个功能应该被删除。- 如果它被保留,函数应该是 const 并返回一个指向 T 的指针:T *x() const;
对于预期的功能。
size
, capacity
和 is_empty
应该都是const
成员函数。
insert_tail
和 remove_tail
问题已在其他人的评论中得到解释(特别是无关的 sizeof
)。
insert_head
的类似问题和 remove_head
还。此外,复制现有项目的代码可以在私有(private)函数中重构,以遵循 DRY 原则并避免代码重复。
关于c++ - C++ 中的模板类和函数重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47763433/
假设我有一个类,我在其中重载了运算符 == : Class A { ... public: bool operator== (const A &rhs) const; ... };
我知道你不应该使用 std::find(some_map.begin(), some_map.end()) 或 std::lower_bound,因为它会采用线性时间而不是 some_map.lowe
我正在尝试在 Haskell 中定义 Vector3 数据类型,并允许在其上使用 (+) 运算符。我尝试了以下方法: data Vector3 = Vector3 Double Double Doub
我已经为我的类图将运算符重载为“-”。它的用途并不完全直观(糟糕的编码 - 我知道)但是如果我做 graph3 = graph2-graph1 那么图 3 是应该只接收图 2 和图 1 中的那些顶点。
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: Operator overloading 我想重载 以按字母顺序排列字符串,但我不确定该怎么做。 如何再次
下面的代码给我一个编译错误。谁能告诉我为什么? class mytype { public: int value; mytype(int a) { value = a;
这有什么问题吗? class Vec2 attr_accessor :x, :y # ... def += (v) @x += v.x @y += v.y retu
是否可以重载 [] 运算符两次?允许这样的事情:function[3][3](就像在二维数组中一样)。 如果可能的话,我想看看一些示例代码。 最佳答案 您可以重载 operator[] 以返回一个对象
我的团队目前正在与 Lua 合作,创建一个 android 游戏。我们遇到的一件事是表面上无法创建重载构造函数。 我习惯于使用默认值设置一个对象,然后在需要时使其过载。 前任: apples() {
我有一个网页,在某个时候显示一个导航栏,它只不过是一个 a 元素的列表 (ul)。所述 a 元素的大多数样式规则都是通用的。唯一应该改变的部分是要显示的图像,可以从列表中每个 li 元素的 id 标签
我对使用/重载“范围步长”运算符(.. ..)很感兴趣,但我终其一生都无法了解如何使用它。 在文档中它说 // Usage: start .. step .. finish 但是在 F# shell
Java 11(可能无关紧要): public static String toString(Object obj) { return ReflectionToStringBuilder.to
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我无法理解以下代码(针对行号进行注释) class Base { void m1(Object o) { } void m2(String o) { } } publi
我有以下代码片段: #include using namespace std; struct Integer{ int x; Integer(const int val) : x(v
class myclass{ //definitions here }; myclass e; int myarray[10]; /* Do something... */ e = myarray;
为什么不能将下标运算符(operator [])作为 friend 函数重载? 最佳答案 正如Bjarne Stroustrup在D&E book中所说: However, even in the o
我有以下代码片段: #include using namespace std; struct Integer{ int x; Integer(const int val) : x(v
因此,我有一个问题是我最近尝试重载 namespace Eng { /** * A structure to represent pixels */ typedef
如何重载onResume()以正确的方式工作?我想从 activity 返回到 MainActivity ,我希望在其中具有与应用程序启动后相同的状态。我想使用 recreate() 但它循环了或者类
我是一名优秀的程序员,十分优秀!