我有一个抽象类“ Mark”,有一个子类“ Int_num”。我也有一个“主题”课程。我希望在调用其构造函数时将指向“ Mark”类的内存中地址的指针写入“ mark”参数。在编译器抱怨“表达式必须具有类类型”或诸如在mark.print_mark()中类似的内容之后,发生了什么使标记指针指向“ Mark”类的事情?”
class Mark {
private:
int mark;
public:
virtual void change_mark(int);
virtual void print_mark();
virtual int return_mark();
};
class Int_mark : public Mark {
private:
int mark;
public:
Int_mark();
Int_mark(int);
~Int_mark();
void change_mark(int = 0);
void print_mark() const;
int return_mark() const;
};
Int_mark::Int_mark() {
std::string str_mark;
std::cout << "New mark: ";
std::cin.ignore();
std::getline(std::cin, str_mark);
str_mark = ltrim(rtrim(str_mark));
int new_mark;
try {
new_mark = stoi(str_mark);
} catch(...) {
std::cout <<"wq";
mark = 1;
return ;
}
try {
if((new_mark < 1) || (new_mark > 5))
throw 1;
else
mark = new_mark;
} catch(int a) {
std::cout << "qw" << std::endl;
mark = 1;
}
}
void Int_mark::print_mark() const {
std::cout << "Mark: " << mark << std::endl;
}
主题
#include "Mark.h"
#include <string>
#include <vector>
class Subject {
private:
std::string name_subject;
std::string type_subject;
unsigned hour_subject = 0;
void *mark = nullptr;
public:
Subject();
Subject(std::string, int);
Subject(std::string, bool);
~Subject();
void change_mark(unsigned);
void change_mark(bool);
void rename_subj(std::string);
void add_hour(unsigned);
};
Subject::Subject() {
std::string name_sub;
std::cout << "Введите название предмета: ";
getline(std::cin, name_sub);
name_sub = split_string(name_sub);
name_subject = name_sub;
int select = 2;
if(select == 1) {
type_subject = "Bool";
//mark = new Bool_mark();
} else {
type_subject = "Int";
mark = new Int_mark();
//What should I do to make the mark pointer point to the "Mark" class?
mark.print_mark();
}
}
主要
#include "subject/Subject.h"
using namespace std;
int main() {
Subject q;
}
我在做什么错?我该怎么办?
答案 0 :(得分:1)
指针mark
的类型为void *
。你可以用
static_cast<Int_mark*>(mark)
并使用调用该函数
static_cast<Int_mark*>(mark)->print_mark();
但是通常在OOP mark
中将是指向基类的指针
Mark *mark = nullptr;
现在,您可以使用
检查错误mark = new Int_mark();
auto *m = dynamic_cast<Int_mark*>(mark);
if (m)
m->print_mark();
记住基类中的虚拟析构函数
virtual ~Mark();
When to use virtual destructors?
这是您代码的固定版本:
#include <iostream>
#include <string>
#include <vector>
class Mark {
public:
virtual ~Mark() = default;
//virtual void change_mark(int) = 0;
virtual void print_mark() const = 0;
//virtual int return_mark() const = 0;
};
class Int_mark : public Mark {
private:
int mark;
public:
Int_mark();
Int_mark(int);
~Int_mark() override = default;
//void change_mark(int = 0) override;
void print_mark() const override;
//int return_mark() const override;
};
Int_mark::Int_mark() {
std::string str_mark;
std::cout << "New mark: ";
std::cin.ignore();
std::getline(std::cin, str_mark);
//str_mark = ltrim(rtrim(str_mark));
int new_mark;
try {
new_mark = stoi(str_mark);
} catch(...) {
std::cout <<"wq";
mark = 1;
return ;
}
try {
if((new_mark < 1) || (new_mark > 5))
throw 1;
else
mark = new_mark;
} catch(int a) {
std::cout << "qw" << std::endl;
mark = 1;
}
}
void Int_mark::print_mark() const {
std::cout << "Mark: " << mark << std::endl;
}
class Subject {
private:
std::string name_subject;
std::string type_subject;
unsigned hour_subject = 0;
Mark *mark = nullptr;
public:
Subject();
Subject(std::string, int);
Subject(std::string, bool);
~Subject();
void change_mark(unsigned);
void change_mark(bool);
void rename_subj(std::string);
void add_hour(unsigned);
};
Subject::Subject() {
std::string name_sub;
std::cout << "Введите название предмета: ";
getline(std::cin, name_sub);
//name_sub = split_string(name_sub);
name_subject = name_sub;
int select = 2;
if(select == 1) {
type_subject = "Bool";
//mark = new Bool_mark();
} else {
type_subject = "Int";
mark = new Int_mark();
auto *m = dynamic_cast<Int_mark*>(mark);
if (m)
m->print_mark();
}
}
Subject::~Subject() {
delete mark;
}
int main() {
Subject q;
}
答案 1 :(得分:0)
由于我一开始对问题的理解不正确,因此介绍了一种如何通过派生类Mark
的对象调用基类Int_Mark
的成员函数的方法:
Int_mark *mark = new Int_mark();
mark->print_mark(); // calls member of the class Int_mark
mark->Mark::print_mark(); // calls member of the class Mark
确保也定义了Mark::print_mark()
,而不仅仅是Int_mark::print_mark()