Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> стражи хидера не охраняют при инклуде!( 
V
    Опции темы
WiND
Дата 11.2.2010, 11:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 3.12.2006

Репутация: нет
Всего: нет



Сорри, заезжанная тема, но несмотря на то, что я прочитал много и все делаю по правилам,у меня не выходит)
к делу:
Файлы: Client.h/Client.cpp, MyFuncs.h, main.cpp
содержание:

Client.h:
Код

#pragma once
#include <windows.h>
#include <string.h>
#include "MyFuncs.h"

class CClient
{
public:
    CClient(void);
    ~CClient(void);
};


Client.cpp:
Код

#include "Client.h"

CClient::CClient(void)
{
}

CClient::~CClient(void)
{
}


MyFuncs.h:
Код

#pragma once
#include <string.h>
#include <Windows.h>

void StrToUpper(char *str)
{
    for (int i = 0; str[i] != NULL; i++)
    {
        str[i] = toupper(str[i]);
    }
}

int IndexOf(char *str, const char *substr)
{
    return (int)(strstr(str,substr)-str);
}


main.cpp:
Код

#pragma once
#include <windows.h>
#include "Client.h"
#include "MyFuncs.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
                   LPSTR lpszCmdLine, int nCmdShow)
{
    char *str = "string";
    int i = IndexOf(str, "t");
    return 0;
}


даже в main.cpp добавил #pragma once )
пробовал и другой способ :#ifndef xxx #define xxx #endif
Ошибки:
Код

Error    2    error LNK2005: "int __cdecl IndexOf(char *,char const *)" (?IndexOf@@YAHPADPBD@Z) already defined in main.obj    Client.obj
Error    1    error LNK2005: "void __cdecl StrToUpper(char *)" (?StrToUpper@@YAXPAD@Z) already defined in main.obj    Client.obj
Error    3    fatal error LNK1169: one or more multiply defined symbols found    PATH\IncludeTester.exe


даже в main.cpp добавил #pragma once )
пробовал и другой способ :#ifndef xxx #define xxx #endif
Вот что не так?! Мне файл MyFuncs.h в дальнейшем почти везде понадобится, а подключить получается тольк однажды. будто не работает #ifndef и #pragma once
PM MAIL   Вверх
xvr
Дата 11.2.2010, 12:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Это не стражи виноваты - они работают, иначе все развалилось бы еще на этапе компиляции, а не линковки. Это повторное определение функций (из .h) файла в нескольких единицах трансляции.
Добавь inline в их определение
Код

#pragma once
#include <string.h>
#include <Windows.h>
inline void StrToUpper(char *str)
{
    for (int i = 0; str[i] != NULL; i++)
    {
        str[i] = toupper(str[i]);
    }
}
inline int IndexOf(char *str, const char *substr)
{
    return (int)(strstr(str,substr)-str);
}

PM MAIL   Вверх
Alca
Дата 11.2.2010, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 2
Всего: 50



Глянь

Присоединённый файл ( Кол-во скачиваний: 5 )
Присоединённый файл  Test.zip 15,62 Kb


--------------------
PM WWW ICQ Skype Jabber   Вверх
Alca
Дата 11.2.2010, 12:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 2
Всего: 50



Разбей свой MyFuncs.h на h-ник и cpp-шник

Это сообщение отредактировал(а) Alca - 11.2.2010, 12:48


--------------------
PM WWW ICQ Skype Jabber   Вверх
bilbobagginz
Дата 12.2.2010, 15:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Naughtius Maximus
****


Профиль
Группа: Экс. модератор
Сообщений: 8813
Регистрация: 2.3.2004
Где: Israel

Репутация: нет
Всего: 317



Цитата(WiND @  11.2.2010,  10:45 Найти цитируемый пост)
MyFuncs.h:

WiND
терминология:
файл .h - хедер (заголовок) - это место, где ты объявляешь классы, методы, и функции.
файл .cpp - исходник, это место, где ты реализуешь объявленное, определяешь.
единственное исключение - это inline функции/методы - когда ты их определяешь в заголовке.
напр. твои функции лучше всего объявить так:
Код

// filename: MyFuncs.h
#pragma once
#include <string.h>
#include <Windows.h>

void StrToUpper(char *str);
int IndexOf(char *str, const char *substr);

а определить так:
Код

// filename: MyFuncs.cpp
#include "MyFuncs.h"

void StrToUpper(char *str)
{
    for (int i = 0; str[i] != NULL; i++)
    {
        str[i] = toupper(str[i]);
    }
}
int IndexOf(char *str, const char *substr)
{
    return (int)(strstr(str,substr)-str);
}


Использовать же функции и методы inline имеет смысл лишь в редких случаях, 
когда это улучшает скорость выполнения программы.
т.е. когда выполнение функции значительно короче, чем прыжок в обычную функцию 
(т.е. сохраниение регистров процессора, стека и т.д.).
Когда ты указываешь, что функция - inline, каждый ее вызов при компиляции заменяется ее кодом (похоже на макро),
в отличие от обычной функции, когда каждый ее вызов переносит контроль кода в другое место, где код функции находится.
Думаю правило "буравчика" в решении использовать или нет inline можно так:
для сохранения регистров и др. нужной информации при вызове функции нужно 
несколько машинных комманд, и это ессно занимает некоторое время.

Если функция-кандидат - не имеет циклов, и делает какие-то очень быстрые действия, то имеет смысл ее сделать inline, т.к.
сохранение данных, стека и т.д. 2 раза займет дольше времени, чем выполнить код здесь и сейчас.

А если функция - цикл (напр. strstr - обязательно цикл, и for(){} - тоже), то использовать inline - не стоит с т.з. скорости и величины программы.

но я - не гуру по C++, просьба гуру C++: 
если я не прав прошу меня ... поправить!


Это сообщение отредактировал(а) bilbobagginz - 12.2.2010, 15:41


--------------------
Я ещё не демон. Я только учусь.
PM WWW   Вверх
bsa
Дата 12.2.2010, 16:18 (ссылка) |    (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



inline это рекомендация компилятору. Он может ее молча игнорировать. Что собственно и делает при отключенной оптимизации (а то невозможно отлаживать программу).
Нет ничего плохого в использовании циклов внутри inline-функций. Почти вся STL состоит из inline- функций/методов.
При вызове функций регистры не сохраняются. Просто эта операция не очень быстрая.
По умолчанию inline лучше использовать для функций типа геттеров и сеттеров, логика которых не предполагает сложных вычислений. Обычно, они возвращают/устанавливают значение переменной класса.
Так же без inline невозможно пока что делать шаблонные методы и функции. Так как далеко не все компиляторы поддерживают extern template - нельзя использовать шаблоны там, где не доступно их определение (реализация).
С другой стороны, как я уже написал выше, iniline - это только рекомендация. Компилятор, если сочтет нужным, сделает ее обычной функцией, которую будет вызывать при необходимости стандартным образом. Причем, эта функция будет единой для всех единиц трансляции (т.е. дублирования кода не будет).
PM   Вверх
bilbobagginz
Дата 12.2.2010, 16:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Naughtius Maximus
****


Профиль
Группа: Экс. модератор
Сообщений: 8813
Регистрация: 2.3.2004
Где: Israel

Репутация: нет
Всего: 317



 smile спасибки, bsa-джан.


--------------------
Я ещё не демон. Я только учусь.
PM WWW   Вверх
WiND
Дата 12.2.2010, 17:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 3.12.2006

Репутация: нет
Всего: нет



Спасибо за ответы)
Т.е без разницы, использую я inline или нет? 
Как лучше поступить?
Так 
MyFuncs.h
Код

#pragma once
#include <string.h>
#include <Windows.h>
inline void StrToUpper(char *str)
{
    for (int i = 0; str[i] != NULL; i++)
    {
        str[i] = toupper(str[i]);
    }
}
inline int IndexOf(char *str, const char *substr)
{
    return (int)(strstr(str,substr)-str);
}


Или так

MyFuncs.h
Код

#pragma once
#include <string.h>
#include <Windows.h>

void StrToUpper(char *str);
int IndexOf(char *str, const char *substr);

MyFuncs.cpp
Код

#include "MyFuncs.h"
void StrToUpper(char *str)
{
    for (int i = 0; str[i] != NULL; i++)
    {
        str[i] = toupper(str[i]);
    }
}

int IndexOf(char *str, const char *substr)
{
    return (int)(strstr(str,substr)-str);
}


ЗЫ: Еще вопрос всплыл. 
Определяю макросы, где обычная конкатенация строковых литералов. с переменным числом параметров
#define MSG_1(param1, param2) "MSG1 " ## param1 ## " " ## param2
#define MSG_1(param1, param2б param3) "MSG2 " ## param1 ## " " ## param2 ## " " ## param3
...
Эти макросы будут часто использоваться, соответственно будет много констант с одним и тем же текстом. 
Думал заменить текст в макросах на константы, но это непозволительно.
Как лучше поступить? создать отдельную функцию?
или создать функцию, вызывающую эти макросы, тогда кол-во их будет одинарным? Отказаться вообще от макросов?
(Понимаю, дрянь эти макросы(дефайн и т.п) но почему-то меня к ним патологически тянет)


Это сообщение отредактировал(а) WiND - 12.2.2010, 17:32
PM MAIL   Вверх
Alca
Дата 12.2.2010, 17:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 2
Всего: 50



То что я предложил

Добавлено через 11 секунд
 smile 


--------------------
PM WWW ICQ Skype Jabber   Вверх
WiND
Дата 12.2.2010, 17:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 3.12.2006

Репутация: нет
Всего: нет



2Alca, А чем будет лучше тогда? 
лично я не хочу из-зв двух(мб 3х) мизерный функций создавать еще срр файл. просто когда много файлов - путает сознание)
Но вместе с этим, хочется делать правильно) Несмотря на подробные ответы, они противоричивы и слегка сбили меня с толку) И так сходу я не понял разницы) вот и спрос ))
PM MAIL   Вверх
unicuum
Дата 12.2.2010, 17:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 830
Регистрация: 16.3.2005
Где: Рашка

Репутация: нет
Всего: 8



Цитата(WiND @  12.2.2010,  17:22 Найти цитируемый пост)
Или так

Да, вот так.


--------------------
user posted image
обычный день на винграде
PM   Вверх
Alca
Дата 12.2.2010, 17:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 2
Всего: 50



Цитата

2Alca, А чем будет лучше тогда? 

раздутие кода 100%-во не будет



--------------------
PM WWW ICQ Skype Jabber   Вверх
bilbobagginz
Дата 12.2.2010, 17:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Naughtius Maximus
****


Профиль
Группа: Экс. модератор
Сообщений: 8813
Регистрация: 2.3.2004
Где: Israel

Репутация: нет
Всего: 317



Цитата(Alca @  12.2.2010,  16:54 Найти цитируемый пост)
раздутие кода 100%-во не будет

раздутие какого кода?



--------------------
Я ещё не демон. Я только учусь.
PM WWW   Вверх
Alca
Дата 12.2.2010, 17:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 2
Всего: 50



Цитата

но почему-то меня к ним патологически тянет

а чем тебя функции не устроили?

Добавлено @ 17:59
Цитата

раздутие какого кода?

инлайного

Добавлено @ 18:00
Цитата

Т.е без разницы, использую я inline или нет? 

Если у него проект маленький, то пофиг что юзать.

Добавлено @ 18:03
Цитата

просто когда много файлов - путает сознание)

два вместо одного  smile

Добавлено @ 18:04
это у тебя тут 2-3 функции, а если 20-30? И всех их заинлайнить? Тогда возможно раздутие кода.

Добавлено @ 18:13
Если на то пошло, тогда пихай классы в один файл. Меньше файлов - меньше путаниц.  smile  

Это сообщение отредактировал(а) Alca - 12.2.2010, 18:14


--------------------
PM WWW ICQ Skype Jabber   Вверх
mes
Дата 12.2.2010, 18:28 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(WiND @  12.2.2010,  16:22 Найти цитируемый пост)
Определяю макросы, где обычная конкатенация строковых литералов. с переменным числом параметров
Эти макросы будут часто использоваться, соответственно будет много констант с одним и тем же текстом. 

все одинаковые строковые литералы современный компилятор самостоятельно "объединяет", т.е. в теле программы будут определены единожды.




--------------------
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1614 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.