我正在尝试学习如何正确分离类标头和代码
I'm trying to learn how to properly separate class header and code
我有一个大学时做的"有效"的课堂项目,但没有正确构建。
它有一个日期类和一个人员类。
在我的"工作"代码中,所有类数据(构造函数、成员和函数)都包含在每个类的单个头文件中(每个类的单独文件)。
该程序将文本文件数据(人物、总统和演员)加载到矢量中,在控制台上对数据进行排序、过滤和打印,并将其保存到文件中。
在 Person 类构造函数(和函数)中,Date 类为"birthdate"对象实例化。然后在程序中使用生日。
我遇到的问题是这样的:
如果所有类代码都在每个类的头文件中,并且我使 Date 成为 Person 的"父"类,我可以轻松地在 Person 构造函数和成员中实例化"Date"。但是,如果我不做这两件事,那么"人"对"日期"一无所知,也无法从日期实例化任何东西。
如果我在 Person.h 中使用 #include"Date.h",这会产生更多问题并且也不起作用。
当然,"Date"不是"Person"的合适父类,但这是我破解代码使其工作的唯一方法,哈哈。当我几年前在大学里第一次编写代码时,我从来没有想过如何正确地划分类代码,以便它能够编译和运行。头文件中包含所有类代码的"工作代码"是我的黑客。我想学习如何以正确的方式做到这一点。
我已经粘贴了下面的最低限度的例子,说明什么"有效",什么无效。任何使此代码适用于分为头文件和.cpp文件的类的提示将不胜感激。
什么有效:
class Date {
private:
int month;
int day;
int year;
public:
Date::Date() {}
virtual ~Date() {}
Date( int aMonth, int aDay, int aYear ) {
this->month = aMonth;
this->year = aYear;
this->day = aDay;
}
// "Getter" functions for the Date class
int getMonth(){return this->month;}
int getYear() {return this->year;}
int getDay() {return this->day;}
// "Setter" functions for the Date class
void setDay( int aDay ){ this->day = aDay; }
void setMonth( int aMonth ) { this->month = aMonth; }
void setYear( int aYear ) { this->year = aYear; }
};
class Person : public Date{
private:
string title;
string firstName;
string lastName;
Date birthDate;
public:
Person::Person() {}
Person(string title, string firstName, string lastName, Date birthDay);
virtual ~Person() {}
//"Getter" functions for the Person class
string getTitle() { return title; }
string getFirstName() { return firstName; }
string getLastName() { return lastName; }
Date getBirthDay() { return birthDate; }
//"Setter" functions for the Person class
void setTitle(string Title) { this->title = Title; }
void setFirstName(string fName) { this->firstName = fName; }
void setLastName (string lName) { this->lastName = lName; }
void setBirthday (Date aBirthday) { this->birthDate = aBirthday; }
};
什么不起作用(不编译):
日期.h
class Date {
private:
int month;
int day;
int year;
public:
Date();
virtual ~Date() {}
Date( int aMonth, int aDay, int aYear );
//Getters and setters
int getMonth();
int getYear() ;
int getDay();
void setDay( int aDay );
void setMonth( int aMonth ) ;
void setYear( int aYear ) ;
};
日期.cpp
#include "Date.h"
Date::Date() {}
Date::Date( int aMonth, int aDay, int aYear ) {
this->month = aMonth;
this->year = aYear;
this->day = aDay;
}
int Date::getMonth(){return this->month;}
int Date::getYear() {return this->year;}
int Date::getDay() {return this->day;}
//"Setter" functions for the Date class
void Date::setDay( int aDay ){ this->day = aDay; }
void Date::setMonth( int aMonth ) { this->month = aMonth; }
void Date::setYear( int aYear ) { this->year = aYear; }
人.h
#include <string>
class Person{
private:
string title;
string firstName;
string lastName;
Date birthDate;
public:
//Person::Person() {}
Person(string title, string firstName, string lastName, Date birthDay);
//"Getter" functions for the Person class
string getTitle() { return title; }
string getFirstName() { return firstName; }
string getLastName() { return lastName; }
Date getBirthDay() { return birthDate; }
//"Setter" functions for the Person class
void setTitle(string Title) { this->title = Title; }
void setFirstName(string fName) { this->firstName = fName; }
void setLastName (string lName) { this->lastName = lName; }
void setBirthday (Date aBirthday) { this->birthDate = aBirthday; }
};
人.cpp
#include "Person.h"
#include <iostream>
using namespace std;
//Person class constructor with 0 arguments
Person::Person(string atitle, string afirstName, string alastName, Date abirthDay) {
title = atitle,
firstName = afirstName,
lastName = alastName,
birthday = abirthDay)
}
//"Getter" functions for the Person class
string Person::getTitle() { return title; }
string Person::getFirstName() { return firstName; }
string Person::getLastName() { return lastName; }
Date Person::getBirthDay() { return birthDate; }
//"Setter" functions for the Person class
void Person::setTitle(string Title) { this->title = Title; }
void Person::setFirstName(string fName) { this->firstName = fName; }
void Person::setLastName (string lName) { this->lastName = lName; }
void Person::setBirthday (Date aBirthday) { this->birthDate = aBirthday; }
操作系统说明
我在 Windows 7 PC 上使用 MS Visual Studio 2012 Update 4。
若要防止重定义错误,请将包含保护添加到头文件。要便于携带,请使用:
#if !defined(THE_HEADER_NAME_H)
#define THE_HEADER_NAME_H
// Usual code and declarations here.
#endif
在 Visual Studio 中,您可以使用:
#pragma once
// Usual code and declarations here.
在标头中,不要写入(在全局范围级别)
using namespace XXXXX
因为这将导致包括您的文件在内的所有文件也使用他们可能不希望强加给他们的命名空间 XXXXX。如果使用命名空间中的类型,请使用命名空间键入整个类型名称,因此请使用:
std::string getTitle()
(在 cpp 文件中,您可以在任何 #includes 后使用"使用命名空间 XXXXX")
我直言,您有 2 个问题。
首先是斯科特·朗厄姆的回答将解决的警卫问题。
第二个是命名空间问题。
我假设在您的工作源代码中,您有(直接间接通过 stdafx.h 或其他包括):
#include <string>
using namespace std;
不建议在.h
头文件中using namespace std;
...但这意味着您应该使用 std::string
而不是 string
:
日期.h
class Date {
private:
int month;
int day;
int year;
public:
Date::Date() { } //Date class constructor with 0 arguments
virtual ~Date() {} //Date class destructor
Date( int aMonth, int aDay, int aYear ) { //Date class constructor with 3 arguments
this->month = aMonth; // Set the private member data with the argument data
this->year = aYear;
this->day = aDay;
}
//"Getter" functions for the Date class
int getMonth(){return this->month;}
int getYear() {return this->year;}
int getDay() {return this->day;}
//"Setter" functions for the Date class
void setDay( int aDay ){ this->day = aDay; }
void setMonth( int aMonth ) { this->month = aMonth; }
void setYear( int aYear ) { this->year = aYear; }
};
person.h (字符串 -> std::字符串和删除方法实现)
#include <string>
#include "Date.h"
class Person : public Date{
private: //Private data members
std::string title;
std::string firstName;
std::string lastName;
Date birthDate;
public:
Person::Person() {} //Person class constructor with 0 arguments
Person(std::string title,
std::string firstName,
std::string lastName,
Date birthDay); //Person class constructor with 4 arguments
virtual ~Person(){} //Person class destructor
//"Getter" functions for the Person class
std::string getTitle();
std::string getFirstName();
std::string getLastName();
Date getBirthDay();
//"Setter" functions for the Person class
void setTitle(std::string Title);
void setFirstName(std::string fName);
void setLastName (std::string lName);
void setBirthday (Date aBirthday);
};
人.cpp(固定包含和构造函数)
#include <string>
#include "Person.h"
#include <iostream>
using namespace std;
//Person class constructor with 0 arguments
Person::Person(string atitle, string afirstName, string alastName, Date abirthDay) {
title = atitle,
firstName = afirstName,
lastName = alastName,
birthDate = abirthDay;
}
//"Getter" functions for the Person class
string Person::getTitle() { return title; }
string Person::getFirstName() { return firstName; }
string Person::getLastName() { return lastName; }
Date Person::getBirthDay() { return birthDate; }
//"Setter" functions for the Person class
void Person::setTitle(string Title) { this->title = Title; }
void Person::setFirstName(string fName) { this->firstName = fName; }
void Person::setLastName (string lName) { this->lastName = lName; }
void Person::setBirthday (Date aBirthday) { this->birthDate = aBirthday; }
它甚至可以在没有防护装置的情况下使用,但无论如何,护卫都是一种很好的做法。
事实上,由于Date.h
包含在Person.h
它确实应该有一个防护装置 - 为简单起见,此处未显示
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 代码在main()中运行,但在函数中出现错误
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 编译包含字符串的代码时遇到问题
- 我在c++代码中生成了一个运行时#3异常
- 如何在linux终端中同时编译和运行c++代码
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- 在Linux for Windows上编译C++代码时出错
- 我的字符计数代码计算错误.为什么
- 分离类所有权和使用,生成最佳(快速)代码
- 当我分离编译和链接时,代码不构建
- 无法分离标头和cpp文件(包括错误和代码)
- C/C++中的6502仿真器:如何将寻址模式代码与实际指令代码分离
- 我正在尝试学习如何正确分离类标头和代码
- 分离配置代码和算法代码的最佳做法
- 将类代码分离为标头和cpp文件
- 从客户端代码和服务器代码中分离OpenGL依赖
- SDL和c++类..如何分离这段代码
- 分离c++代码时出现编译错误
- 使用CRTP分离平台特定的代码