gpt4 book ai didi

c++ - << 使用继承和模板定义

转载 作者:行者123 更新时间:2023-11-30 05:42:32 25 4
gpt4 key购买 nike

<分区>

我正在尝试使用模板在 C++ 中实现链表。不幸的是,当我尝试使用 ostream 时遇到 Unresolved external 错误。本站类似问题的解答说是头文件和.cpp文件不匹配,我觉得这里不是。谁能帮我解决这个问题,我真的需要掌握这一点。

链表.h:

#ifndef LINKEDLIST_H
#define LINKEDLIST_H

#include <string>
#include <iostream>

template<class T> class LinkedList;

// Class representing a templated linkedlist element
template<class T> class LLElement {
friend class LinkedList<T>;
public:
// Constructor
LLElement(T* p_Data) : data(p_Data), next(NULL) {}

T* getData() const { return data; }
LLElement<T>* getNext() { return next; }
private:
LLElement<T>* next;
T* data;
};

// Class representing a templated linked list
template<class T> class LinkedList {
public:
LinkedList() : size(0), start(NULL) {}
LinkedList(const LinkedList&);
~LinkedList();

unsigned int getSize() const { return size; }
LLElement<T>* getStart() const { return start; }

//adds shallow copy of T to the LinkedList
void sortedAdd(T*);
//removes the first occurence of T from the LinkedList
void remove(T*);
//merges existing LinkedList with given LinkedList
void merge(const LinkedList<T>&);
//formatted print of LinkedList to given outputstream
void showLinkedList(std::ostream& p_Out) const;
friend std::ostream& operator<<(std::ostream& outputStream, const LinkedList<T>& sec);

private:
LLElement<T>* start;
unsigned int size;
};

//LinkedList copy constructor
//TODO
template<class T> LinkedList<T>::LinkedList(const LinkedList<T>& a){
this->size=a.getSize();
this->start=a.getStart();
}

// LinkedList destructor
// TODO
template<class T> LinkedList<T>::~LinkedList(){
LLElement<T>* a=this->getStart();
LLElement<T>* b=a->next;
while(a!=NULL){
delete a;
a=b;
b=a->next;
}

}


// sortedAdd
// adds shallow copy of T to the LinkedList
// TODO
template<class T> void LinkedList<T>::sortedAdd(T* add){
LLElement<T>* a=new LLElement<T>(add);
LLElement<T>* b=this->getStart();
while(!(*(b->data)<=*(a->getData()))){
b=b->next;
}
a->next=b->next;
b->next=a;
this->size++;
}



// remove
// removes the first occurence of T from the LinkedList
// TODO
template<class T> void LinkedList<T>::remove(T* ab){
LLElement<T>* a=this->getStart();
LLElement<T>* b=this->getStart();
while(a!=NULL){
if(*(a->data)==*(ab)){
if(b==a){
this->start=a->next;
delete a;
this->size--;
return;
}
b->next=a->next;
delete a;
this->size--;
return;
}
b=a;
a=b->getNext();
}
}


// TODO output operator

template<class T> std::ostream& operator<<(std::ostream& outputStream, const LinkedList<T>& sec){
sec.showLinkedList(outputStream);
return outputStream;
}
//merges existing LinkedList with given LinkedList
template<class T> void LinkedList<T>::merge(const LinkedList<T>& p_LL){
LLElement<T> *cursor = p_LL.start;
while (cursor != NULL){
sortedAdd(cursor->data);
cursor = cursor->next;
}
}

//formatted print of LinkedList to given outputstream
template<class T> void LinkedList<T>::showLinkedList(std::ostream& p_Out) const {
LLElement<T>* current = start;
int counter = 1;
p_Out << "LINKEDLIST OF SIZE " << size << std::endl;
while (current != NULL){
p_Out << "LL ELEMENT " << counter++ << " : ";
p_Out << *(current->getData()) << std::endl;
current = current->getNext();
}
}

#endif

错误:

Error   2   error LNK2019: unresolved external symbol "class
std::basic_ostream<char,struct std::char_traits<char> > & __cdecl
operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class
LinkedList<class CMSContent> const &)" (??6@YAAAV?$basic_ostream@DU
$char_traits@D@std@@@std@@AAV01@ABV?$LinkedList@VCMSContent@@@@@Z) referenced in function "public: void __thiscall CMS::print(void)" (?print@CMS@@QAEXXZ) C:\Users\knudde\Documents\Visual Studio 2012\Projects\Ex1314\Ex1314\CMS.obj Ex1314

也许 CMSContent 有问题?

内容.h:

#ifndef H_CONTENT
#define H_CONTENT

#include <map>
#include <set>
#include <iostream>
#include <string>

enum ACCESSRIGHT { owner, modify, read, none };

class CMSContent {
public:
CMSContent(std::string p_Id, std::string p_Username);

void addPermissionUser(ACCESSRIGHT p_Right, std::string p_Username);
ACCESSRIGHT getAccessright(std::string p_Username);

std::string getIdentifier(){ return identifier; };
virtual std::string serialise() const=0;
bool CMSContent::operator< (const CMSContent& param) const;
bool CMSContent::operator<= (const CMSContent& param) const;
bool CMSContent::operator== (const CMSContent& param) const;
friend std::ostream& operator<<(std::ostream& outputStream, CMSContent& secondOperand);
protected:
std::string identifier;
std::map<ACCESSRIGHT, std::set<std::string> > accessrightsByRank;
//map with key accessright and value set of usernames with given access right
private:
void setIdentifier(std::string p_Id){ identifier = p_Id; };
bool userHasHigherAccessRight(ACCESSRIGHT p_Right, std::string p_Username);
void removeLowerAccessRights(ACCESSRIGHT p_Right, std::string p_Username);

static int uniqueID;
};

class Project : public CMSContent {
public:
Project(std::string p_Name, std::string p_Description, std::string p_Username);

virtual std::string serialise() const;

std::string getProjectdescription(){ return projectdescription; };
void setProjectdescription(std::string p_Description){ projectdescription = p_Description; };
protected:
std::string projectdescription;
};

class Document : public CMSContent {
public:
Document(std::string p_Name, std::string p_Username, std::string p_URL);
virtual std::string serialise() const;

std::string getURL(){ return URL; };
void setURL(std::string p_Url){ URL = p_Url; };
protected:
std::string URL;
};

class HowTo : public CMSContent {
public:
HowTo(std::string p_Subject, std::string p_Howto_content, std::string p_Username);
virtual std::string serialise() const;

std::string getHowto_content() { return howto_content; }
void setHowto_content(std::string p_Howto_content) { howto_content = p_Howto_content; }
protected:
std::string howto_content;
};

#endif

内容.cpp:

#include "Content.h"
#include <sstream>

CMSContent::CMSContent(std::string p_Id, std::string p_Username) : identifier(p_Id){
accessrightsByRank[owner].insert(p_Username);
}

void CMSContent::addPermissionUser(ACCESSRIGHT right, std::string p_Username) {
if (!userHasHigherAccessRight(right, p_Username)){
removeLowerAccessRights(right, p_Username);
accessrightsByRank[right].insert(p_Username);
}
}

bool CMSContent::operator< (const CMSContent& param) const{
return (this->identifier.compare(param.identifier)<0);
}

bool CMSContent::operator<= (const CMSContent& param) const{
return (this->identifier.compare(param.identifier)<=0);
}

bool CMSContent::operator== (const CMSContent& param) const{
return (this->identifier.compare(param.identifier)==0);
}

std::ostream& operator<<(std::ostream& outputStream, CMSContent& cont){
outputStream<<cont.serialise();
outputStream<<"owner = ";
std::set<std::string>::iterator a,b;
a=cont.accessrightsByRank[owner].begin();
b=cont.accessrightsByRank[owner].end();
while(a!=b){
outputStream << (*a) <<std::endl;
}
outputStream<<"modify = ";

a=cont.accessrightsByRank[modify].begin();
b=cont.accessrightsByRank[modify].end();
while(a!=b){
outputStream << (*a) <<std::endl;
}
outputStream<<"read = ";

a=cont.accessrightsByRank[read].begin();
b=cont.accessrightsByRank[read].end();
while(a!=b){
outputStream << (*a) <<std::endl;
}
return outputStream;
}

bool CMSContent::userHasHigherAccessRight(ACCESSRIGHT right, std::string p_Username){
//TODO
if(right==owner){return false;}
std::map<ACCESSRIGHT, std::set<std::string> >::iterator beg, end;
std::set<std::string> ::iterator beg1, end1;
beg=accessrightsByRank.begin();
end=accessrightsByRank.find(right);
while(beg != end){
beg1=(*beg).second.begin();
end1=(*beg).second.end();
while(beg1!=end1){
if((*beg1).compare(p_Username)==0){
return true;
}
beg1++;
}
beg++;
}
return false;
}

void CMSContent::removeLowerAccessRights(ACCESSRIGHT right, std::string p_Username){
//TODO
std::map<ACCESSRIGHT, std::set<std::string> >::iterator beg, end;
std::set<std::string> ::iterator beg1, end1;
end=accessrightsByRank.end();
beg=accessrightsByRank.find(right)++;
while(beg != end){
beg1=(*beg).second.begin();
end1=(*beg).second.end();
while(beg1!=end1){
if((*beg1).compare(p_Username)==0){
(*beg).second.erase(beg1);
return;
}
beg1++;
}
beg++;
}
}

Project::Project(std::string p_Identifier, std::string p_Description, std::string p_Username) : CMSContent("P;"+p_Identifier, p_Username){
projectdescription = p_Description;
}

std::string Project::serialise() const {
std::stringstream output;
output << "Project name = " << identifier << std::endl;
output << "Project description = " << projectdescription << std::endl;
return output.str();
}

Document::Document(std::string p_Identifier, std::string p_Username, std::string p_URL) : CMSContent("D;"+p_Identifier, p_Username){
URL = p_URL;
}

std::string Document::serialise() const {
std::stringstream output;
output << "Document name = " << identifier << std::endl;
output << "Document URL = " << URL << std::endl;
return output.str();
}

HowTo::HowTo(std::string p_Identifier, std::string p_Howto_content, std::string p_Username) : CMSContent("H;"+p_Identifier, p_Username){
howto_content = p_Howto_content;
}

std::string HowTo::serialise() const{
std::stringstream output;
output << "Howto subject = " << identifier << std::endl;
output << "Howto content = " << howto_content << std::endl;
return output.str();
}

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com