提问人:Khalid Abdallah 提问时间:8/2/2023 最后编辑:mrtomblueKhalid Abdallah 更新时间:8/2/2023 访问量:127
在 c++ 中使用命名空间和单独编译
Using namespaces and separate compilation in c++
问:
我正在尝试在我创建的新类上首次使用命名空间和单独编译。但是,我遇到了一个错误,上面写着.我不确定我做错了什么。unresolved external symbol
这是头文件
#pragma once
////File name: COP3014KA.h
//Author: Khalid Abdallah
//assignment number: 4
//description: Using classes and derived classes to create objects within the classes. includes constructors to intilize.
//Last Changed: August 2, 2023
//header file for class COP3014
#ifndef COP3014_H
#define COP3014_H
#include <iostream>
#include <string>
using namespace std;
namespace Abdallah //new namespace for class
{
// COP3014 class
class COP3014 {
protected:
string firstName, lastName, zNumber;
int quiz1, quiz2, quiz3, midterm, finalExam;
double totalGrade;
char letterGrade;
public:
// Constructors
COP3014();// default constructor initializes all values to 0
COP3014(string fname, string lname, string znum); //intializes all values to the maximum
void input(); //gets inputs from the user for each field
// Setter functions
void setFirstName(string fname);
void setLastName(string lname);
void setZNumber(string znum);
void setQuiz1(int grade);
void setQuiz2(int grade);
void setQuiz3(int grade);
void setMidterm(int grade);
void setFinalExam(int grade);
// Getter functions
string getFirstName() const;
string getLastName() const;
string getZNumber() const;
int getQuiz1() const;
int getQuiz2() const;
int getQuiz3() const;
int getMidterm() const;
int getFinalExam() const;
double getTotalGrade() const;
char getLetterGrade() const;
// Grade computation function
void computeTotalGrade();
// Letter grade computation function
void computeLetterGrade();
// Absent check function
void checkAbsences();
// Output function
void printInfo() const;
};
}
#endif
实现
//File name: KhalidAbdallah_Assignment3.cpp
//Author: Khalid Abdallah
//assignment number: 4
//description: Using classes and derived classes to create objects within the classes. includes constructors to intilize.
//Last Changed: August 2, 2023
//implementation file
#include <iostream>
#include <string>
#include "COP3014KA.h"
using namespace std;
using namespace Abdallah;
// COP3014 class
class COP3014 {
protected:
string firstName, lastName, zNumber;
int quiz1, quiz2, quiz3, midterm, finalExam;
double totalGrade;
char letterGrade;
public:
// Constructors
COP3014()// default constructor
{
firstName = "student";
lastName = "name";
zNumber = "11111111";
quiz1 = 0;
quiz2 = 0;
quiz3 = 0;
midterm = 0;
finalExam = 0;
}
COP3014(string fname, string lname, string znum)
{
firstName = fname;
lastName = lname;
zNumber = znum;
quiz1 = 20;
quiz2 = 20;
quiz3 = 20;
midterm = 100;
finalExam = 100;
}
void input() //gets inputs from the user for each field
{
cout << "Enter first name: " << endl;
cin >> firstName;
cout << "Enter last name: " << endl;
cin >> lastName;
cout << "Enter z number: " << endl;
cin >> zNumber;
do
{
cout << "Enter quiz 1 grade: " << endl;
cin >> quiz1;
} while (quiz1 < 0 || quiz1 > 20);
do
{
cout << "Enter quiz 2 grade: " << endl;
cin >> quiz2;
} while (quiz2 < 0 || quiz2 > 20);
do
{
cout << "Enter quiz 3 grade: " << endl;
cin >> quiz3;
} while (quiz3 < 0 || quiz3 > 20);
cout << "Enter midterm grade: " << endl;
cin >> midterm;
cout << "Enter final exam grade: " << endl;
cin >> finalExam;
}
// Setter functions
void setFirstName(string fname)
{
firstName = fname;
}
void setLastName(string lname)
{
lastName = lname;
}
void setZNumber(string znum)
{
zNumber = znum;
}
void setQuiz1(int grade)
{
quiz1 = grade;
}
void setQuiz2(int grade)
{
quiz2 = grade;
}
void setQuiz3(int grade)
{
quiz3 = grade;
}
void setMidterm(int grade)
{
midterm = grade;
}
void setFinalExam(int grade)
{
finalExam = grade;
}
// Getter functions
string getFirstName() const
{
return firstName;
}
string getLastName() const
{
return lastName;
}
string getZNumber() const
{
return zNumber;
}
int getQuiz1() const
{
return quiz1;
}
int getQuiz2() const
{
return quiz2;
}
int getQuiz3() const
{
return quiz3;
}
int getMidterm() const
{
return midterm;
}
int getFinalExam() const
{
return finalExam;
}
double getTotalGrade() const
{
return totalGrade;
}
char getLetterGrade() const
{
return letterGrade;
}
// Grade computation function
void computeTotalGrade() {
totalGrade = ((quiz1 + quiz2 + quiz3) / 3.0) + (midterm * 0.3) + (finalExam * 0.5);
}
// Letter grade computation function
void computeLetterGrade() {
if (totalGrade >= 90) {
letterGrade = 'A';
}
else if (totalGrade >= 80 && totalGrade <= 90) {
letterGrade = 'B';
}
else if (totalGrade >= 70 && totalGrade <= 80) {
letterGrade = 'C';
}
else if (totalGrade >= 60 && totalGrade <= 70) {
letterGrade = 'D';
}
else {
letterGrade = 'F';
}
}
// Absent check function
void checkAbsences() {
if (midterm <= 0 || finalExam <= 0)
letterGrade = 'F';
}
// Output function
void printInfo() const {
cout << firstName << " " << lastName << " - " << zNumber << endl;
cout << "Quiz 1: " << quiz1 << endl;
cout << "Quiz 2: " << quiz2 << endl;
cout << "Quiz 3: " << quiz3 << endl;
cout << "Mid term: " << midterm << endl;
cout << "Final: " << finalExam << endl;
cout << "Total grade: " << totalGrade << endl;
cout << "Final grade: " << letterGrade << endl;
}
};
应用程序
//File name: COP3014KA_APP.cpp
//Author: Khalid Abdallah
//assignment number: 4
//description: Using classes and derived classes to create objects within the classes. includes constructors to intilize.
//Last Changed: August 2, 2023
//Application file for COP3014KA.cpp
//uses header and implementation files.
#include <iostream>
#include <string>
#include "COP3014KA.h"
using namespace std;
using namespace Abdallah;
int main()
{
//sample test cases
COP3014 student1("Frank", "Fabulous", "Z12345678");
student1.setQuiz1(20);
student1.setQuiz2(20);
student1.setQuiz3(10);
// Set midterm and final exam grades
student1.setMidterm(0);
student1.setFinalExam(100);
// Compute the total grade and letter grade
student1.computeTotalGrade();
student1.computeLetterGrade();
student1.checkAbsences();
// Print student information and grades
student1.printInfo();
cout << endl;
COP3014 student2("Gina ", "Genius ", "Z98765432");
student2.setQuiz1(20);
student2.setQuiz2(20);
student2.setQuiz3(20);
// Set midterm and final exam grades
student2.setMidterm(98);
student2.setFinalExam(95);
// Compute the total grade and letter grade
student2.computeTotalGrade();
student2.computeLetterGrade();
student2.checkAbsences();
// Print student information and grades
student2.printInfo();
cout << endl;
COP3014 student3;
student3.input();
cout << endl;
// Compute the total grade and letter grade
student3.computeTotalGrade();
student3.computeLetterGrade();
student3.checkAbsences();
// Print student information and grades
student3.printInfo();
cout << endl;
}
我尝试链接文件,但我相信它们没有链接。它可能与定义的命名空间有关,因为文件之间没有传输任何内容。
答:
1赞
tbxfreeware
8/2/2023
#1
下面的评论应该可以回答您的大部分问题。
头文件应包含声明,但不应包含定义。例如:
// This is a function declaration. There is no function body.
int f();
//
This is a function definition. It has a function body.
int g() {
return 42;
}
好的,这里是头文件。它包含一个示例类声明和一个示例函数声明。因为声明出现在命名空间中,所以它们是可见的。它们在命名空间之外的“文件级”范围内不可见。MyClass.h
tbx
请注意,函数返回一个 类型的对象。这应该很有趣。my_factory
MyClass
#ifndef MYCLASS_H
#define MYCLASS_H
namespace tbx
{
class MyClass
{
public:
// these are all declarations, no definitions
static int my_static_variable;
int my_instance_variable;
MyClass();
void my_member_function();
};
MyClass my_factory();
}
#endif // MYCLASS_H
// end file: MyClass.h
接下来,我们有文件 .它包含标题中事物的定义。这要棘手得多,所以我写了很多评论来解释为什么有些名称必须限定范围,而另一些则不需要限定范围。MyClass.cpp
#include "MyClass.h"
// We are at "file-level" scope.
// Static member variables be must scoped:
// once to enter the namespace, and then again to enter the class.
// From there, the name of the static variable is visible.
int tbx::MyClass::my_static_variable = 42;
// The same goes for the constructor function.
// Scope once to enter namespace, and then again to enter class.
// From there, the name of the constructor function is visible.
tbx::MyClass::MyClass()
: my_instance_variable( 7 ) // Now we are inside the class,
{} // so no scoping is needed.
// This is file-level scope.
// Must scope to namespace to find class name.
// Must scope again to enter class and find function.
void // This return type does not require scoping, ...
tbx::MyClass::my_member_function() // but the function name does.
{
// Now we are inside the scope of MyClass.
// Names do not have to be scoped here.
my_instance_variable = 8;
}
// This is still file-level scope.
// Must scope to namespace in order see function declared there.
// Must also scope to namespace in order to identify the return type.
tbx::MyClass // The return type requires scoping.
tbx::my_factory() // So does the function name.
{
// No scoping is needed to refer to MyClass from inside the function.
//
// The `tbx::` which prefixes `my_factory` causes us
// to enter the namespace. After that, any name visible
// in the namespace is also visible inside the function.
// That is why MyClass is visible here.
//
// The closing brace at the end of the function
// causes us to exit namespace.
MyClass mc; // no scoping needed here.
return mc;
}
// end file: MyClass.cpp
最后,该文件只是一个简单的测试驱动程序。main.cpp
#include "MyClass.h"
int main()
{
// Scoping required to see inside the namespace.
tbx::MyClass mc;
mc = tbx::my_factory();
return 0;
}
// end file: main.cpp
对函数使用尾随返回类型的一大优点是,如果返回类型使用的名称与函数本身在同一作用域中可见,则不必限定返回类型的范围。
将函数的这个定义与上面给出的定义进行比较。这个定义可以在文件中使用,而不是上面写的:my_factory
MyClass.cpp
auto tbx::my_factory() -> MyClass // at this point we are inside
{ // the scope of the the namespace.
MyClass mc; // Therefore, MyClass does not need
return mc; // any scoping
}
您可以以任何一种方式进行操作,但如今,大多数人都选择尾随返回类型。
评论
COP3014
Abdallah
using namespace Abdallah;
namespace Abdallah { // code here that implement class members }
使用命名空间
,作者:Jason Turner,每周C++。using namespace std;
COP3014KA.h
using namespace