为什么指针不写入类的地址?

Why doesn't the pointer write the address of the class?

本文关键字:地址 指针 为什么      更新时间:2023-10-16

我有一个抽象类"Mark",它有一个子类"Int_num"。我还有一节"主题"课。我希望在调用"Mark"类的构造函数时,将指向该类内存中地址的指针写入"Mark"参数。我应该怎么做才能使标记指针指向"mark"类?在编译器抱怨mark.print_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;
}

我做错了什么?我该怎么做?

指针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();

何时使用虚拟析构函数?

以下是您代码的固定版本:

#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;
}

由于我一开始没有正确理解这个问题,这里有一种方法可以通过派生类Int_Mark的对象调用基类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()