Генератор паролей
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
Посетила меня идея создать генератор паролей при помощи класса.
Файл
main.cpp
:Файл
KeyGen.h
:Файл
KeyGen.cpp
:Вроде ничего ошибочного нет. Но не компилируется. С ошибкой:
KeyGen.cpp:(.text+0x0): multiple definition of
_strlen(char const*)'` и так на каждый метод класса. В чём проблема?Не изобретай велосипед. Функция вычисления длины строки с концевым нулём есть в стандартной библиотеке.
Кроме того, ты слишком перемудрил с кодом. Придерживайся принципа KISS.
Кроме того, обнаружилось, что ты забыл про концевой ноль в строке пароля.
И опять cpp-файл в
#include
((Я слил всё в один файл и немного соптимизировал.
А вообще-то говоря, класс здесь не нужен. Достаточно было бы функции, которая генерировала бы пароль в буфер, предоставляемый вызывающим кодом. Что-то типа такого:
Череп, может я чего-то не понимаю, но если я включу в файл
main.cpp
только файлKeyGen.h
, то откуда компилятор возьмёт реализацию методов, если она есть только в файлеKeyGen.cpp
, который не включен в файлmain.cpp
?Я попытался разбить ваш код на файлы(правильно или нет?):
Файл
main.cpp
:Файл
KeyGen.h
:Файл
KeyGen.cpp
:И тут появилась ошибка:
'string' does not name a type
к файлуKeyGen.h
и
'string' was not declared in this scope
к файлуKeyGen.cpp
. В чём прикол?Я не знаю каким компилятором и IDE ты пользуешься, поэтому не могу тебе ответить точно на первый вопрос.
Если ты пользуешься IDE, то в них существует понятие «проекта». В проекте указываются все файлы исходного кода, ресурсы и т.п., зависимости между ними, а также порядок «изготовления» выходного файла (это может быть исполняемый модуль, библиотека, динамическая библиотека и т.п.): порядок вызовов компилятора, линкера, библиотекаря и пр., а также параметры их вызовов. В этом случае тебе надо добавить в проект все три файла.
Если ты работаешь по старинке, вызывая компилятор из командной строки, то тебе сначала надо все cpp-файлы откомпилировать в объектные файлы, а затем линкером всё собрать в один exe'шник.
Код разбил на файлы в общем-то правильно. Единственно, в h-файл надо добавить защиту от множественного включения,
#include <iostream>
и включение пространства имёнstd
дляstring
иostream
:По поводу ошибок, которые ты получил: это скорее всего от того, что не включено пространство имён
std
.Я сейчас проверил твою версию моего кода (с вышеуказанными правками) под Dev-C++ 5.5.3 — всё компилится и собирается нормально.
Что то я не понял, то есть если я создаю проект(DevCpp 5.4.2, все три файла в проекте), то все связи между файлами устанавливает линкер? и мне не надо
их соединять с помощью
#include
?И ещё, не могли бы вы мне объяснить, немного, как работает защита от множественного включения(и почему её нет в файле
KeyGen.cpp
?) или кинуть ссылку где про это говорится, а то по запросуC++ защита от множественного включения
я ничего не нашёл...http://ru.wikipedia.org/wiki/Include_guard
Череп, selevit, спасибо, и извините, сильно тупил, а вы как всегда всё «разжевали» и «разложили по полочкам».
Да, IDE сама откомпилирует и свяжет все файлы проекта.
Директива препроцессора
#include
— это просто вставка содержимого файла, указанного в директиве, вместо самой директивы на уровне текста. Это происходит до компиляции.Поэтому у тебя директива
#include "KeyGen.h"
должна быть в файлах main.cpp и KeyGen.h, что бы объявить класс KeyGen. Откомпилированное определение (реализация) класса будет подтянуто линкером.Защита от множественного включения работает до безобразия просто. Вот она:
У препроцессора имеется таблица символов, куда он заносит все символы, определённые директивами
#define
и определённые в командной строке препроцессора (компилятора).Когда файл KeyGen.h попадается препроцессору в первый раз, происходит следующее. Первая директива — это условная компиляция: если указанный символ не определён (IF Not DEFined). Символ
_KEYGEN_H_
не определён, условие выполняется, будет обрабатываться следующая строка текста. Вторая директива — определение символа_KEYGEN_H_
. Далее идёт текст, который препроцессор выводит в выходной поток (для компиляции). Директива#endif
закрывает блок условной компиляции.Когда файл KeyGen.h попадается препроцессору в следующий раз, символ
_KEYGEN_H_
будет уже определён. Поэтому условие в первой директиве не выполнится и весь текст до директивы#endif
включительно не будет выведен в выходной поток и не будет откомпилирован.Это классический случай.
Есть альтернативный способ: директива компилятора
Но это, что называется, «особенности реализации», зависящие от компилятора. А директивы препроцессора работают везде.
Рекомендую почитать в книжке про директивы препроцессора.
Извиняюсь, недоглядел. Файл KeyGen.h должен выглядеть так:
а определение констант должно быть перенесено в файл KeyGen.cpp:
Почему-то компилятор не счёл это ошибкой и даже не выдал предупреждения. Хотя при включении файла KeyGen.h в KeyGen.cpp и main.cpp должно было получиться два набора констант и при линковке должны были появиться ошибки о переопределении символов. Чудеса однако ((