gpt4 book ai didi

c++ - 编译器将派生类视为实际定义的抽象引用函数

转载 作者:太空宇宙 更新时间:2023-11-04 14:50:05 25 4
gpt4 key购买 nike

我正在为 Acellerated c++ 第 15 章编译代码。我或多或少地直接从书中复制代码,除了在某些地方,它们在头文件的类主体中定义了诸如构造函数之类的东西,而且我将它们分开以避免链接错误。

下面是代码;我试图在 Visual Studio 2010 中编译它,但不幸的是它失败了。它告诉我它不能创建“String_Pic”和其他派生类(Frame_Pic、HCat_Pic 和 VCat_Pic)的实例,因为它说它们仍然是抽象类。它说罪魁祸首是“显示”功能,它说这是未定义的。但是,我为每个派生类都明确定义了它,如下所示。

这是怎么回事?

标题:

#ifndef _GUARD_PIC_BASE_H
#define _GUARD_PIC_BASE_H

#include "Ptr.h"
#include <iostream>
#include <string>
#include <vector>


class Picture;

class Pic_base {
friend std::ostream& operator<<(std::ostream&, const Picture&);
friend class Frame_Pic;
friend class HCat_Pic;
friend class VCat_Pic;
friend class String_Pic;


typedef std::vector<std::string>::size_type ht_sz;
typedef std::string::size_type wd_sz;


virtual wd_sz width() const = 0;
virtual ht_sz height() const = 0;
virtual void display(std::ostream, ht_sz, bool) const = 0;

public:
virtual ~Pic_base(){ }

protected:
static void pad(std::ostream&, wd_sz, wd_sz);
};

// public interface class and operations
class Picture {
friend std::ostream& operator<<(std::ostream&, const Picture&);
friend Picture frame(const Picture&);
friend Picture hcat(const Picture&, const Picture&);
friend Picture vcat(const Picture&, const Picture&);

public:
Picture(const std::vector<std::string>& =
std::vector<std::string>());
private:
Picture(Pic_base* ptr); //here's one difference
Ptr<Pic_base> p;
};


Picture frame(const Picture&);
Picture hcat(const Picture&, const Picture&);
Picture vcat(const Picture&, const Picture&);
std::ostream& operator<<(std::ostream&, const Picture&);

class String_Pic: public Pic_base {
friend class Picture;
std::vector<std::string> data;
String_Pic(const std::vector<std::string>&);

wd_sz width() const;
ht_sz height() const;
void display(std::ostream&, ht_sz, bool) const;
};

class VCat_Pic: public Pic_base {
friend Picture vcat(const Picture&, const Picture&);
Ptr<Pic_base> top, bottom;
VCat_Pic(const Ptr<Pic_base>&, const Ptr<Pic_base>&);

wd_sz width() const;
ht_sz height() const;
void display(std::ostream&, ht_sz, bool) const;
};

class HCat_Pic: public Pic_base {
friend Picture hcat(const Picture&, const Picture&);
Ptr<Pic_base> left, right;
HCat_Pic(const Ptr<Pic_base>&, const Ptr<Pic_base>&);

wd_sz width() const;
ht_sz height() const;
void display(std::ostream&, ht_sz, bool) const;
};

class Frame_Pic: public Pic_base {
friend Picture frame(const Picture&);
Ptr<Pic_base> p;
Frame_Pic(const Ptr<Pic_base>& pic);

wd_sz width() const;
ht_sz height() const;
void display(std::ostream&, ht_sz, bool) const;
};

#endif

.cpp/执行文件:

#include "Ptr.h"
#include "Pic_Base.h"
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>

using namespace std;

//Picture-Specific Functions:

Picture::Picture(Pic_base* ptr):p(ptr) {}

Picture::Picture(const vector<string>& v): p(new String_Pic(v)) { }

//Frame-Specific Functions:

Frame_Pic::Frame_Pic(const Ptr<Pic_base>& pic): p(pic) {}

Pic_base::wd_sz Frame_Pic::width() const { return p->width() + 4; }

Pic_base::ht_sz Frame_Pic::height() const { return p->height() + 4; }

void Frame_Pic::display(ostream& os, ht_sz row, bool do_pad) const{
if (row >= height()) {
// out of range
if (do_pad)
pad(os, 0, width());
} else {
if (row == 0 || row == height() - 1) {

// top or bottom row
os << string(width(), '*');
} else if (row == 1 || row == height() - 2) {

// second from fop or bottom row
os << "*";
pad(os, 1, width() - 1);
os << "*";
} else {
// interior row
os << "* ";
p->display(os, row - 2, true);
os << " *";
}
}
}

Picture frame(const Picture& pic){
return new Frame_Pic(pic.p);
}

//HCat-Specific Functions:

HCat_Pic::HCat_Pic(const Ptr<Pic_base>& l, const Ptr<Pic_base>& r): left(l), right(r) { }

HCat_Pic::HCat_Pic(const Ptr<Pic_base>& l, const Ptr<Pic_base>&r):
left(l), right(r) { }

Pic_base::wd_sz width() const { return left->width() + right->width(); }

Pic_base::ht_sz height() const { return max(left->height(), right->heigth()); }

void HCat_Pic::display(ostream& os, ht_sz row, bool do_pad) const{
left->display(os, row, do_pad || row < right->height());
right->display(os, row, do_pad);
}

Picture hcat(const Picture& l, const Picture& r){
return new HCat_Pic(l.p, r.p);
}

//VCat-Specific Functions:

VCat_Pic::VCat_Pic(const Ptr<Pic_base>& t, const Ptr<Pic_base>& b): top(t), bottom(b) { }

Picture vcat(const Picture& t, const Picture& b){
return new VCat_Pic(t.p, b.p);
}

Pic_base::wd_sz VCat_Pic::width() const {
return max(top->width(), bottom->width());
}

Pic_base::ht_sz VCat_Pic::height() const{
return top->height() + bottom->height();
}

void VCat_Pic::display(ostream& os, ht_sz row, bool do_pad) const{
wd_sz w = 0;
if (row < top->height()) {
// we are in the top subpicture
top->display(os, row, do_pad);
w = top->width();
} else if (row < height()) {
// we are in the bottom subpicture
bottom->display(os, row - top->height(), do_pad);
w = bottom->width();
}
if (do_pad)
pad(os, w, width());
}

//String_Pic-Specific Functions:

String_Pic::String_Pic(const std::vector<std::string>& v): data(v) { }

Pic_base::ht_sz String_Pic::height() const { return data.size(); }

Pic_base::wd_sz String_Pic::width() const{
Pic_base::wd_sz n = 0;
for (Pic_base::ht_sz i = 0; i != data.size(); ++i)
n = max(n, data[i].size());
return n;
}

void String_Pic::display(ostream& os, ht_sz row, bool do_pad) const{
wd_sz start = 0;

// write the row if we're still in range
if (row < height()) {
os << data[row];
start = data[row].size();
}

// pad the output if necessary
if (do_pad)
pad(os, start, width());
}

//Pic_base-Specific functions:
void Pic_base::pad(std::ostream& os, wd_sz beg, wd_sz end) {
while (beg != end) {
os << " ";
++beg;
}
}


//Non-Specific Functions:

ostream& operator<<(ostream& os, const Picture& picture){
const Pic_base::ht_sz ht = picture.p->height();
for (Pic_base::ht_sz i = 0; i != ht; ++i) {
picture.p->display(os, i, false);
os << endl;
}
return os;
}

最佳答案

您将纯虚函数声明为采用 ofstream 按值获取对象,而您所有的子类都将其定义为获取对一个对象的引用 .

virtual void display(std::ostream, ht_sz, bool) const = 0;

对比

void display(std::ostream&, ht_sz, bool) const;
^

关于c++ - 编译器将派生类视为实际定义的抽象引用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14331244/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com