- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我很难将我编写的 C++ 类与单独的“测试”C++ 文件链接起来。所以我有这三个文件:threadtest.cc、Elevator.h 和 Elevator.cc。在 Elevator.h 中,我定义了两个类:Passenger 和 Elevator。当我尝试从 threadtest.cc 文件中引用 Passenger 或 Elevator 的函数时,出现 undefined reference 错误。我做的第一件事是确保我在 threadtest.cc 中有一个 include 指令。我一直在尝试到处搜索链接和 NACHOS 类的指南,但我唯一能找到的是 Roadmap To NACHOS pdf,它缺少出现此类问题时所需的详细信息。
我包括了 Elevator.h、threadtest.cc 和 Makefile 中可能与此链接问题最相关的部分片段。
下面是我在编译时最关心的错误:
threadtest.o(.text+0x1c4):../threads/threadtest.cc:103: undefined reference to `Passenger::FromFloor()'
threadtest.o(.text+0x1d3):../threads/threadtest.cc:103: undefined reference to `Passenger::ToFloor()'
threadtest.o(.text+0x1e2):../threads/threadtest.cc:103: undefined reference to `Passenger::ID()'
threadtest.o(.text+0x204):../threads/threadtest.cc:104: undefined reference to `Elevator::Request(Passenger*)'
threadtest.o(.text+0x215):../threads/threadtest.cc:106: undefined reference to `Passenger::ID()'
threadtest.o(.text+0x237):../threads/threadtest.cc:107: undefined reference to `Elevator::LoadPassenger(Passenger*)'
threadtest.o(.text+0x248):../threads/threadtest.cc:109: undefined reference to `Passenger::ID()'
threadtest.o(.text+0x26a):../threads/threadtest.cc:110: undefined reference to `Elevator::UnloadPassenger(Passenger*)'
以下是 threadtest.cc 中从第 97 t0 111 行开始的有问题的行:
#include "Elevator.h"
class Passenger;
class Elevator;
void
RunPassenger( int ptr )
{
int *temp = (int*) ptr;
Passenger *P = new Passenger( temp[ 0 ], temp[ 1 ], temp[ 2 ] );
printf( "Person %d wants to go to floor %d from floor %d\n", P->ID( ), P->ToFloor( ), P->FromFloor( ) );
E->Request( P );
printf( "Person %d got into the elevator\n", P->ID( ) );
E->LoadPassenger( P );
printf( "Person %d got out of the elvator\n", P->ID( ) );
E->UnloadPassenger( P );
}
这是我在 Elevator.h 中定义的类
#ifndef ELEVATOR_H
#define ELEVATOR_H
#include "copyright.h"
#include "thread.h"
#include "list.h"
#include "synch.h"
class Passenger
{
private:
int fromFloor;
int toFloor;
int tID;
bool passengerDirection;
public:
Passenger( int fromFloor, int toFloor, int tID );
int FromFloor( );
int ToFloor( );
int ID( );
bool pDirection( );
};
class Elevator
{
public:
Elevator( );
Elevator( int numFloors );
~Elevator( );
int TotalFloors( int numFloors );
Thread* ThreadPtr( );
bool IsAtCapacity( );
bool PassengerDirection( bool direction );
void LoadPassenger( Passenger *P );
void UnloadPassenger( Passenger *P );
void PassengersWaiting( );
void Run( );
void Initialize( );
void AddToQueue( Passenger *P );
void Request( Passenger *P );
private:
Thread *T;
List *Queue, *UpQueue, *DownQueue;
Semaphore *S;
int NumFloors;
int* PassCounter;
int OnBoard;
bool Direction;
int CurrentFloor;
Condition *ElevatorCV;
Condition *PassengerCV;
Lock *lock;
};
#endif
最后,有一个 GNU Makefile 用于编译 NACHOS 中的所有内容。下面是 Makefile 中对应 threadtest.cc 和 Elevator.h 的部分
threadtest.o: ../threads/threadtest.cc ../threads/copyright.h \
../threads/system.h ../threads/utility.h ../threads/bool.h \
../threads/Elevator.h ../threads/Elevator.cc \
../machine/sysdep.h ../threads/copyright.h /usr/include/stdio.h \
/usr/include/features.h /usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h \
/usr/lib/gcc/i386-redhat-linux/3.4.6/include/stddef.h \
/usr/include/bits/types.h /usr/include/bits/wordsize.h \
/usr/include/bits/typesizes.h /usr/include/libio.h \
/usr/include/_G_config.h /usr/include/wchar.h /usr/include/bits/wchar.h \
/usr/include/gconv.h ../threads/stdarg.h /usr/include/bits/stdio_lim.h \
/usr/include/bits/sys_errlist.h /usr/include/string.h \
/usr/include/xlocale.h ../threads/thread.h ../threads/scheduler.h \
../threads/list.h ../machine/interrupt.h ../threads/list.h \
../machine/stats.h ../machine/timer.h ../threads/utility.h
Elevator.o: ../threads/Elevator.cc ../threads/threadtest.h ../threads/copyright.h \
../threads/utility.h ../threads/system.h ../threads/utility.h ../threads/bool.h \
../machine/sysdep.h /usr/include/stdio.h \
/usr/include/features.h /usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h \
/usr/lib/gcc/i386-redhat-linux/3.4.6/include/stddef.h \
/usr/include/bits/types.h /usr/include/bits/wordsize.h \
/usr/include/bits/typesizes.h /usr/include/libio.h \
/usr/include/_G_config.h /usr/include/wchar.h /usr/include/bits/wchar.h \
/usr/include/gconv.h ../threads/stdarg.h /usr/include/bits/stdio_lim.h \
/usr/include/bits/sys_errlist.h /usr/include/string.h \
/usr/include/xlocale.h ../threads/thread.h ../threads/scheduler.h \
../threads/list.h ../machine/interrupt.h ../threads/list.h \
../machine/stats.h ../machine/timer.h ../threads/utility.h
这里是Elevator.cc中所有函数的定义
#include "Elevator.h"
#include "thread.h"
#include "Condition.h"
#include "synch.h"
#define MAX_CAPACITY 5
//----------------------------------------------------------------------
// Elevator::Elevator
// Initialize an elevator, without any parameters
//----------------------------------------------------------------------
Elevator::Elevator( )
{
T = new Thread( "Elevator" );
S = new Semaphore( "Semaphore", 1 );
Queue = new List; UpQueue = new List; DownQueue = new List;
OnBoard = 0;
CurrentFloor = 0;
}
//----------------------------------------------------------------------
// Elevator::Elevator
// Initialize an elevator.
//
// "NumFloors" is the total number of floors an elevator will traverse
// "T" is a new Thread for an elevator
// "S" is a Semaphore that is used for synchronization of elevator
// "Queue" is a List that holds Passengers in the elevator
// "UpQueue" and "DownQueue" hold Passengers waiting for elevator
// "OnBoard" is a counter of the Passengers on the elevator
// "CurrentFloor" is a counter of the floors the elevator has visited
//----------------------------------------------------------------------
Elevator::Elevator( int numFloors ) : NumFloors( numFloors )
{
T = new Thread( "Elevator" );
S = new Semaphore( "Semaphore", 1 );
Queue = new List; UpQueue = new List; DownQueue = new List;
OnBoard = 0;
CurrentFloor = 0;
}
//----------------------------------------------------------------------
// Elevator::Elevator
// Initialize an elevator.
//
// "NumFloors" is the total number of floors an elevator will traverse
// "T" is a new Thread for an elevator
// "S" is a Semaphore that is used for synchronization of elevator
// "Queue" is a List that holds Passengers in the elevator
// "UpQueue" and "DownQueue" hold Passengers waiting for elevator
// "OnBoard" is a counter of the Passengers on the elevator
// "CurrentFloor" is a counter of the floors the elevator has visited
//----------------------------------------------------------------------
Elevator::~Elevator( )
{
delete T;
delete S;
delete Queue;
delete UpQueue;
delete DownQueue;
}
//----------------------------------------------------------------------
// Elevator::TotalFloors
// Initialize the NumFloors variable in the Elevator class.
//----------------------------------------------------------------------
void
Elevator::TotalFloors( int numFloors )
{
this->NumFloors = numFloors;
PassCounter = new int[ numFloors + 1 ];
for( int i = 1; i < numFloors; i++ )
PassCounter[ i ] = 0;
}
//----------------------------------------------------------------------
// Elevator::ThreadPtr
// Returns the Thread responsible for the Elevator functions
//----------------------------------------------------------------------
Thread*
Elevator::ThreadPtr( )
{
return T;
}
//----------------------------------------------------------------------
// Elevator::IsAtCapacity
// Determine if the Elevator has reached its maximum capacity. Returns
// a boolean value.
//----------------------------------------------------------------------
bool
Elevator::IsAtCapacity( )
{
if( this->OnBoard < MAX_CAPACITY )
return false;
return true;
}
//----------------------------------------------------------------------
// Elevator::PassengerDirection
// Determines if the elevator and a passenger are heading in the
// different directions. Returns a boolean value of true if they are
// and a boolean value of false if headed in the same direction.
//
// "direction" is a boolean representing the passenger's direction
//----------------------------------------------------------------------
bool
Elevator::PassengerDirection( bool direction )
{
if( direction && this->Direction )
return false;
if( direction || this->Direction )
return true;
return false;
}
//----------------------------------------------------------------------
// Elevator::LoadPassenger
// Load a new passenger onto the elevator. First check if the elevator
// is at capacity and if the passenger is traveling in the same
// direction. The elevator uses a semaphore before loading the
// passenger onto its queue, and releases the semaphore when it's done.
//
// "p" is a pointer to a passenger struct to extract passenger info
//----------------------------------------------------------------------
void
Elevator::LoadPassenger( Passenger *P )
{
if( this->IsAtCapacity( ) || this->PassengerDirection( P->pDirection( ) ) )
return ;
lock->Acquire( );
AddToQueue( P );
while( CurrentFloor != P->ToFloor( ) )
PassengerCV->Wait( lock );
lock->Release( );
}
//----------------------------------------------------------------------
// Elevator::UnloadPassenger
// Unload a passenger from the elevator. First check if the passenger's
// destination is the same as the current floor. If so, unload the
// passenger and decrement the number of passengers on board. If not,
// then re-add the passenger to the queue at the front of the list.
//
// "p" is a pointer to a passenger struct to extract passenger info
//----------------------------------------------------------------------
void
Elevator::UnloadPassenger( Passenger *P )
{
lock->Acquire( );
if( PassCounter[ CurrentFloor ] == 0 )
ElevatorCV->Signal( lock );
lock->Release( );
}
//----------------------------------------------------------------------
// Elevator::PassengersWaiting
// Determine if a passenger is queued waiting to go up or waiting to go
// down. Depending on the elevator's direction, a passenger will be
// picked up, if one is queued. If one is not queued, then the function
// terminates.
//----------------------------------------------------------------------
void
Elevator::PassengersWaiting( )
{
Passenger *p = 0;
S->P( );
if( Direction )
if( !UpQueue->IsEmpty( ) )
{
p = ( (Passenger *)UpQueue->Remove( ) );
}
if( !Direction )
if( !DownQueue->IsEmpty( ) )
{
p = ( (Passenger *)DownQueue->Remove( ) );
}
if( p != 0 && !PassengerDirection( p->pDirection( ) ) )
LoadPassenger( p );
S->V( );
}
//----------------------------------------------------------------------
// Elevator::Run
// Starts the elevator at floor 1 and runs until floor "NumFloors." The
// elevator prints the floor number when it arrives. It then loops
// through the first passenger in the queue, removing that passenger,
// while the passenger's destination is the current floor. Once all
// passengers are unloaded, we check if the elevator can accommodate
// any additonal passengers.
//----------------------------------------------------------------------
void
Elevator::Run( )
{
ASSERT( OnBoard >= 0 );
while( 1 )
{
lock->Acquire( );
if( Queue->IsEmpty( ) )
ElevatorCV->Wait( lock );
lock->Release( );
while( !( Queue->IsEmpty( ) ) )
{
for( int i = 0; i < 50; i++ )
currentThread->Yield( );
Person *p = Queue->Remove( );
Direction = p->pDirection( );
lock->Acquire( );
if( Direction )
CurrentFloor--;
else if( !Direction )
CurrentFloor++;
printf( "Elevator arrives on floor %d\n", CurrentFloor );
if( CurrentFloor == p->ToFloor )
{
delete p;
PassengerCV->Broadcast( lock );
ElevatorCV->Wait( lock );
}
lock->Release( );
}
lock->Acquire( );
List *TempList = Queue;
if( Direction )
{
Queue = DownQueue;
DownQueue = TempList;
}
else if( !Direction )
{
Queue = UpQueue;
UpQueue = TempList;
}
lock->Release( );
}
}
//----------------------------------------------------------------------
// Elevator::AddToQueue
// Adds a passenger to the UpQueue or the DownQueue from the ThreadTest
// file.
//----------------------------------------------------------------------
void
Elevator::AddToQueue( Passenger *P )
{
if( Queue->IsEmpty( ) )
{
Queue->SortedInsert( (void*) P, P->ToFloor( ) );
OnBoard++;
}
else
{
Person *P2 = (Person*) Queue->Remove( );
if( P->FromFloor( ) != CurrentFloor )
{
if( P2->FromFloor( ) < P->FromFloor( ) )
UpQueue->Append( (void*) P );
else
{
Queue->SortedInsert( (void*) P, P->ToFloor( ) );
OnBoard++;
}
}
else
{
if( P->FromFloor( ) < CurrentFloor )
DownQueue->Append( (void*) P );
else
{
Queue->SortedInsert( (void*) P, P->ToFloor( ) );
OnBoard++;
}
}
Queue->SortedInsert( (void*) P2, P2->ToFloor( ) );
OnBoard++;
}
}
void
Elevator::Request( Person *P )
{
lock->Acquire( );
bool Enter = true;
if( !( Queue->IsEmpty( ) ) )
if( P->FromFloor != CurrentFloor )
Enter = false;
if( CurrentFloor == P->FromFloor( ) && Enter )
{
lock->Release( );
return;
}
AddToQueue( P );
while( CurrentFloor != P->FromFloor )
PassengerCV->Wait( lock );
lock->Release( );
}
//----------------------------------------------------------------------
// Passenger::Passenger
// Initialize a passenger and load the Passenger class' private
// variables.
//
// "atFloor" is an int representing a passenger's origin floor
// "goToFloor" is an int representing a passenger's destination floor
// "PID" is an int representing a passenger's ID
//----------------------------------------------------------------------
Passenger::Passenger( int fromFloor, int toFloor, int tID ): toFloor( toFloor ), fromFloor( fromFloor ), tID( tID )
{
passengerDirection = fromFloor < toFloor;
}
//----------------------------------------------------------------------
// Passenger::ToFloor
// Returns the value of the "toFloor" variable, which represents the
// floor a Passenger wants to reach.
//----------------------------------------------------------------------
int
Passenger::ToFloor( )
{
return this->toFloor;
}
//----------------------------------------------------------------------
// Passenger::FromFloor
// Returns the value of the "fromFloor" variable, which represents the
// floor a Passenger started on.
//----------------------------------------------------------------------
int
Passenger::FromFloor( )
{
return this->fromFloor;
}
//----------------------------------------------------------------------
// Passenger::ID
// Returns the value of the "tID" variable, which represents a
// Passenger's unique identification number. Also, a thread ID for each
// Passenger/Thread.
//----------------------------------------------------------------------
int
Passenger::ID( )
{
return this->tID;
}
//----------------------------------------------------------------------
// Passenger::pDirection
// Returns the value of the "passengerDirection" variable, which
// represents which direction a Passenger is headed. A true value means
// that a Passenger is headed up and a false value means that a
// Passenger is headed down.
//----------------------------------------------------------------------
bool
Passenger::pDirection( )
{
return passengerDirection;
}
任何形式的帮助或想法都将不胜感激!我投资了 Bjarne Stroustrup 的 C++ 编程语言,希望它能在未来帮助解决这类问题。
最佳答案
我记得您必须编辑/code 中的 Makefile.common,然后从那里运行 gmake,它会自动在 NACHOS 中生成目录级 makefile。
如果你打开 Makefile.common,你会看到这些行:
THREAD_H =../threads/copyright.h\
../threads/list.h\
../threads/scheduler.h\
../threads/synch.h \
../threads/synchlist.h\
../threads/system.h\
../threads/thread.h\
../threads/utility.h\
../machine/interrupt.h\
../machine/sysdep.h\
../machine/stats.h\
../machine/timer.h
THREAD_C =../threads/main.cc\
../threads/list.cc\
../threads/scheduler.cc\
../threads/synch.cc \
../threads/synchlist.cc\
../threads/system.cc\
../threads/thread.cc\
../threads/utility.cc\
../threads/threadtest.cc\
../machine/interrupt.cc\
../machine/sysdep.cc\
../machine/stats.cc\
../machine/timer.cc
THREAD_S = ../threads/switch.s
THREAD_O =main.o list.o scheduler.o synch.o synchlist.o system.o thread.o \
utility.o threadtest.o interrupt.o stats.o sysdep.o timer.o
您需要在此处添加行来编译您的 Elevator 类。你这样做了吗?
关于c++ - 从另一个文件引用 C++ 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19190357/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!