我正在尝试编写一个程序,在其中我可以在一个类中编写算法,然后仅在主体中调用运行函数。我目前有一个运行良好的方法,但是当我编写第二个算法时,出现链接器错误
实施欧几里得式gcd算法效果很好,但是当我添加素数时,我开始出现链接器错误
mkdir -p bin
c++ -Iinclude -g -Wall -Wformat -Wno-unknown-pragmas -std=c++11 -c -o bin/main.o src/main.cpp
mkdir -p bin
c++ -Iinclude -g -Wall -Wformat -Wno-unknown-pragmas -std=c++11 -c -o bin/euclidean.o src/euclidean.cpp
mkdir -p bin
c++ -Iinclude -g -Wall -Wformat -Wno-unknown-pragmas -std=c++11 -c -o bin/primes.o src/primes.cpp
c++ -o algorithms bin/main.o bin/euclidean.o bin/primes.o -Iinclude -g -Wall -Wformat -Wno-unknown-pragmas -std=c++11
Undefined symbols for architecture x86_64:
"primes::run(int)", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [algorithms] Error 1
我的文件结构如下:
Makefile
|
|-src/-- main.cpp
| |- euclidean.cpp
| |- primes.cpp
|
|-include/--
|- primes.hpp
|- euclidean.hpp
这是我的Makefile
SOURCEDIR = src
SOURCES := $(shell find $(SOURCEDIR) -name '*.cpp')
VPATH = src:bin
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
BINS = $(addprefix bin/, $(OBJS))
UNAME_S := $(shell uname -s)
CXXFLAGS = -Iinclude
CXXFLAGS += -g -Wall -Wformat -Wno-unknown-pragmas -std=c++11
%.o:%.cpp
mkdir -p bin
$(CXX) $(CXXFLAGS) -c -o bin/$@ $<
all: $(EXE)
@echo Build complete
$(EXE): $(OBJS)
$(CXX) -o $@ $(BINS) $(CXXFLAGS)
clean:
rm -f $(EVE)
rm -rf bin
我的main.cpp
#include "euclidean.hpp"
#include "primes.hpp"
#include <iostream>
int main(int argc, char** argv){
euclidian euc;
primes p;
euc.run(2147483640,1145435640);
p.run(20);
return 0;
}
primes.cpp
#include "primes.hpp"
std::vector<int> sieve(int n){
//Initlize List
std::vector<int> primes;
for(int i = 2; i < n; i++){
primes.push_back(i);
}
for (auto const& c : primes){
std::cout << c << ' ';
}
return primes;
}
std::vector<int> run(int n){
std::cout << "Prime Numbers:" << std::endl;
//Sieve Algorithm
std::cout << "Seive Algorithm" << std::endl;
auto start = std::chrono::steady_clock::now();
std::vector<int> primes = sieve(n);
auto end = std::chrono::steady_clock::now();
auto diff = end - start;
std::cout << "Recursive Execution Time: " << std::chrono::duration <double, std::nano> (diff).count() << " ns" << std::endl;
std::cout << primes.size() << "primes between 0 and "<< n << ": ";
for (auto const& c : primes){
std::cout << c << ' ';
}
std::cout << std::endl << "===================" << std::endl;
return primes;
}
primes.hpp
#include <vector>
#include <iostream>
class primes{
public:
std::vector<int> run(int n);
std::vector<int> sieve(int n);
};
然后那些工作正常euclidean.cpp
#include "euclidean.hpp"
int euclidian::gcdRecursive(int a, int b){
if(b == 0){return a;}
return gcdRecursive(b,a%b);
}
int euclidian::gcdIterative(int a, int b){
while(b != 0){
int temp = b;
b = a%b;
a = temp;
}
return a;
}
int euclidian::run(int a, int b){
std::cout << "Euclidean GCD: " << a << "," << b << std::endl;
//Recursive
auto start = std::chrono::steady_clock::now();
int gcd = gcdRecursive(a,b);
auto end = std::chrono::steady_clock::now();
auto diff = end - start;
std::cout << "Recursive Execution Time: " << std::chrono::duration <double, std::nano> (diff).count() << " ns" << std::endl;
//Iterative
start = std::chrono::steady_clock::now();
gcd = gcdIterative(a,b);
end = std::chrono::steady_clock::now();
diff = end - start;
std::cout << "Iterative Execution Time: " << std::chrono::duration <double, std::nano> (diff).count() << " ns" << std::endl;
std::cout << "GCD: " << gcd << std::endl << "===================" << std::endl;
return gcd;
}
和euclidean.hpp
#include <iostream>
class euclidian{
public:
int run(int a, int b);
private:
int gcdRecursive(int a, int b);
int gcdIterative(int a, int b);
};
[我的最初想法是,可能与Vectors作为返回类型有关,但这并没有什么改变。我试图弄乱Makefile来明确地将文件作为目标。而且我已经从项目中完全删除了欧几里得的东西,但是那也没有解决。
此
std::vector<int> run(int n){
不是同名素类的成员函数的定义。
您必须写
std::vector<int> primes::run(int n){
成员函数sieve
存在相同的问题,必须使用类似的限定名称来定义
std::vector<int> primes::sieve(int n){