Your privacy
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.
07-04-2013
#1
Registered User
07-05-2013
#8
Registered User
Originally Posted by Elysia
One project = one program.
One program consists of many source files that are merged together into one file (executable). A project is a way to keep all these files together and merge them into a single file.
So, to create a new program, create a new project. That’s all.Technically you could just create a separate CB target for each main function.
Tim S.
«…a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match..» Bill Bryson
otreblA_SNAKE_[ITA]
Hi there guys,
I’m studying C++ with Deitel «C++ How To Program» and I’ve done a small «gradebook» program. However I’ve a problem: when I try tu build&run my program I’ve an error:
C:UsersAlbertoAppDataLocalTempccSdybij.o:main.cpp|| multiple definition of `main’|
objDebugmain.o:C:UsersAlbertoDocumentsProgetti C++ CodeBlocksConsoleApplication24main.cpp|10|first defined here|
||=== Build finished: 2 errors, 0 warnings ===|
Here’s my simple program:
gradebook.h
#include <string>
using std::string;class GradeBook
{
public:
GradeBook( string );
void setCourseName( string );
string getCourseName();
void displayMessage();
private:
string courseName;
};
gradebook.cpp
#include <iostream>
using std::cout;
using std::endl;#include "GradeBook.h"
GradeBook::GradeBook( string name )
{
setCourseName( name );
}
void GradeBook::setCourseName( string name )
{
if ( name.length() <= 25 )
courseName = name;
if ( name.length() > 25 )
{
courseName = name.substr( 0, 25 );
cout << "Name "" << name << "" exceeds maximum lenght (25).n" << "Limiting courseName to first 25 characters.n" << endl;
}
}
string GradeBook::getCourseName()
{
return courseName;
}
void GradeBook::displayMessage()
{
cout << "Welcome to the GradeBook forn" << getCourseName() << "!" << endl;
}
Main.cpp
#include <iostream>
using std::cout;
using std::endl;#include "GradeBook.h"
int main()
{
//creazione di due oggetti GradeBook
GradeBook gradeBook1( "CS101 Introduction to C++ Programming" );
GradeBook gradeBook2( "CS102 Data Structures in C++" );
cout << "gradeBook1's initial name is: " << gradeBook1.getCourseName() << "ngradeBook2's initial name is: " << gradeBook2.getCourseName() << endl;
gradeBook1.setCourseName( "CS101 C++ Programming" );
cout << "ngradeBook1's course name is: " << gradeBook1.getCourseName() << "ngradeBook2's course name is: " << gradeBook2.getCourseName() << endl;
return 0;
}
In my «Linker Settings» I’ve included both gradebook.h and gradebook.cpp files but that doesn’t help
Thank you,
otreblA
« Last Edit: June 23, 2010, 11:40:07 am by otreblA_SNAKE_[ITA] »
Logged
Глобальный модератор
Offline
Пол:
Внимание! Люблю сахар в кубиках!
P.S. Разве так сложно написать (компилятору), что он не знает какой main запустить, потому что их больше одного в проекте… Криворукие программисты
а это что написано?
multiple definition of `main’ , first defined here
научись читать. умник нашелся.
можешь спросить, а где номер строчки? и я тебе отвечу, линкер не обязан быть в курсе каким образом были получены объектные файлы, точнее компиляция какой комбинации исходных кодов привела к появлению этих файлов, за это отвечает компилятор.
Вот натолкнулся на проблему: знаю путь к папке, но как проверить, что это именно папка, а не файл?
если линукс, то используем stat
во кусок из BOOST
status_api( const std::string & ph, error_code & ec )
{
struct stat path_stat;
if ( ::stat( ph.c_str(), &path_stat ) != 0 )
{
if ( errno == ENOENT || errno == ENOTDIR )
{
ec = ok;
return fs::file_status( fs::file_not_found );
}
ec = error_code( errno, system_category );
return fs::file_status( fs::status_unknown );
}
ec = ok;
if ( S_ISDIR( path_stat.st_mode ) )
return fs::file_status( fs::directory_file );
if ( S_ISREG( path_stat.st_mode ) )
return fs::file_status( fs::regular_file );
if ( S_ISBLK( path_stat.st_mode ) )
return fs::file_status( fs::block_file );
if ( S_ISCHR( path_stat.st_mode ) )
return fs::file_status( fs::character_file );
if ( S_ISFIFO( path_stat.st_mode ) )
return fs::file_status( fs::fifo_file );
if ( S_ISSOCK( path_stat.st_mode ) )
return fs::file_status( fs::socket_file );
return fs::file_status( fs::type_unknown );
}
есть такой кусок для винды, но принцип тот же:
template< class String >
fs::file_status status_template( const String & ph, error_code & ec )
{
DWORD attr( get_file_attributes( ph.c_str() ) );
if ( attr == 0xFFFFFFFF )
{
ec = error_code( ::GetLastError(), system_category );
if ((ec.value() == ERROR_FILE_NOT_FOUND)
|| (ec.value() == ERROR_PATH_NOT_FOUND)
|| (ec.value() == ERROR_INVALID_NAME) // «tools/jam/src/:sys:stat.h», «//foo»
|| (ec.value() == ERROR_INVALID_PARAMETER) // «:sys:stat.h»
|| (ec.value() == ERROR_BAD_PATHNAME) // «//nosuch» on Win64
|| (ec.value() == ERROR_BAD_NETPATH)) // «//nosuch» on Win32
{
ec = ok; // these are not considered errors;
// the status is considered not found
return fs::file_status( fs::file_not_found );
}
else if ((ec.value() == ERROR_SHARING_VIOLATION))
{
ec = ok; // these are not considered errors;
// the file exists but the type is not known
return fs::file_status( fs::type_unknown );
}
return fs::file_status( fs::status_unknown );
}
ec = ok;;
return (attr & FILE_ATTRIBUTE_DIRECTORY)
? fs::file_status( fs::directory_file )
: fs::file_status( fs::regular_file );
}
Я часами застреваю над проблемой, которая, вероятно, очень тривиальна.
Это самое основное использование классов.
Заголовочный файл: person.h
class person
{
protected:
std::string _Name;
public:
void setName(std::string);
};
Реализация: person.cpp
#include <string>
#include "person.h"
void person::setName(std::string name)
{
_Name = name;
}
Драйвер: main.cpp
#include <iostream>
#include "person.cpp"
int main()
{
std::cout << "Yes, it worked.n";
return 0;
}
При попытке скомпилировать этот код в CodeBlocks (используя GNU GCC), я получаю сообщение об ошибке:
~person.cpp|5|multiple definition of `person::setName(std::string)'|
~person.cpp|5|first defined here|
||=== Build finished: 2 errors, 0 warnings (0 minutes, 0 seconds) ===|
У меня есть прототип в заголовочном файле и тело в файле реализации. Где множественное определение? Это работает, если я добавлю «inline» перед «void» в person.cpp, но зачем мне в этом случае?
Кроме того, при компиляции того же точного кода в cmd, что и «g ++ main.cpp -o main.exe», он работает отлично (без встроенного)!
2
Решение
Вам не нужно включать *.cpp
файл в main.cpp. Вы должны включить *.h
файл.
Короче — *.cpp
Файлы содержат реализацию и скомпилированы компилятором. *.h
файлы содержат определения и могут быть включены из *.cpp
файлы. Когда вы включаете *.cpp
файл, вы получите несколько определений одного и того же объекта.
Кроме того, вам нужно добавить включить охрану
#ifndef MY_HEADER
#define MY_HEADER
... code of your header file ...
#endif
или просто добавь
#pragma once
если ваш компилятор поддерживает это.
4
Другие решения
произошло ли это сегодня.
при добавлении файла в кодовые блоки с помощью file — new и т. д. появляется экран, который спрашивает, хотите ли вы включить файл в отладочную и выпускную версии. Вы невинно отвечаете «да», ставя галочки. в результате файл автоматически включается, и когда вы явно включаете его самостоятельно, вы в конечном итоге дублируете. поэтому не ставьте галочки в этих клетках.
ура
толстяк-коротышка
2
Вы можете включить файл .cpp в другой .cpp в кодовых блоках. Но не добавляйте его в проект, который вы создали. Если файл включен в проект, блоки кода будут пытаться скомпилировать его следующим образом:
g ++ main.cpp -o main.o
g ++ person.cpp -o person.o
и затем создайте окончательный выходной файл, используя два .o файла. Поскольку main.cpp включает в себя func.cpp, вы столкнетесь с ошибкой множественного объявления.
Теперь, если вы оставите в проекте только файл main.cpp, только он будет скомпилирован, и вы не получите ту же ошибку.
0