"unresolved externals" bei statischer Methode

Gast #1699328
Lesenswert?

DE_handler.h
1
#pragma once
2
#include "stdafx.h"
3

4
class DE_handler
5
{
6
public:
7
  int main(void);
8
  DE_handler(void);
9
  static vector<float> mul_vec(vector<float>, float k);
10
  static vector<float> add_vec(vector<float>, vector<float>);
11
};

DE_handler.cpp
1
#include "DE_handler.h"
2
#include "equation.h"
3

4
int main(void)
5
{
6
  float time = 0.0;
7
  float t_end = 10.0;
8
  float h = 1;
9
  vector<float> c; //constants
10
  vector<float> initial; //initial values
11
  vector<float> temp_res; //temporary stored results
12
  vector<vector<float>> results; //calculated results
13

14
  //define vector of constants belonging to the differential equation
15
  c.push_back(1/4);
16
  c.push_back(-1/100);
17
  c.push_back(-1);
18
  c.push_back(1/100);
19

20
  //define initial values
21
  initial.push_back(80.0);
22
  initial.push_back(30.0);
23

24
  equation eq(c);
25
  temp_res = initial;
26

27
  temp_res = DE_handler::add_vec(initial, initial);
28
  cout << temp_res.at(0) << " " << temp_res.at(1);
29

30
  system("Pause");
31
  return 0;
32
}
33

34
static vector<float> mul_vec(vector<float> vec, float k)
35
  {
36
    for(int i = 0; i <= vec.size(); i++)
37
    {
38
      vec.at(i) = vec.at(i)*k;
39
    }
40
    return vec;
41
  }
42

43
static vector<float> add_vec(vector<float> vec1, vector<float> vec2)
44
  {
45
    vector<float> sum;
46
    for(int i = 0; i < vec1.size(); i++)
47
    {
48
      sum.push_back(vec1.at(i)+vec2.at(i));
49
    }
50
    return sum;
51
  }
52

53
DE_handler::DE_handler(void)
54
{
55
}

Die genaue Meldung des Compilers:
"Error  3  error LNK2019: unresolved external symbol "public: static 
class std::vector<float,class std::allocator<float> > __cdecl 
DE_handler::add_vec(class std::vector<float,class std::allocator<float> 
>,class std::vector<float,class std::allocator<float> >)" 
(?add_vec@DE_handler@@SA?AV?$vector@MV?$allocator@M@std@@@std@@V23@0@Z) 
referenced in function _main 
D:\Dokumente\Studium\NDGL\NDGL_P1\NDGL_P1\DE_handler.obj  NDGL_P1
"

Ich komme nicht drauf, was dem Compiler fehlt. Wenn ich die Zeile
1
temp_res = DE_handler::add_vec(initial, initial);
auskommentiere, gibt es diesen Fehler nicht. Anscheinend kann der 
Compiler die Methode add_vec() nicht finden, oder wie?
Gast #1700183
Lesenswert?

Zu main(): Das Programm wird ausgeführt, auch wenn kein Objekt von 
DE_handler erstellt wurde. Die main()-Methode funktioniert bestens ... 
Wo ist das Problem?

Ansonsten läuft es jetzt. Musste die Klasse vor die Methode schreiben. 
Mit static hatte der Compiler dann auch Probleme. Anscheinend darf 
static vor der Methode nur in der Headerdatei stehen, nicht aber im 
Quellcode, oder?

Ich stolper über viele Sachen in C++, weil ich davor lange in Java 
programmiert habe. Vor allem die ganzen Deklarationen und die 
Headerdateien verwirren mich.
Gast #1700203
Lesenswert?

Maxim schrieb:
> Zu main(): Das Programm wird ausgeführt, auch wenn kein Objekt von
> DE_handler erstellt wurde. Die main()-Methode funktioniert bestens ...
> Wo ist das Problem?

Das funktioniert aber nur, weil du vor main eben nicht den Klassen-Namen 
geschrieben hast. Damit ist deine Funktion main aus der DE_Handler 
Klasse noch undefiniert. Zum Glück rufst du die auch nicht auf, so dass 
der Linker keinen Grund hat zu meckern.

Also: raus mit dem main() aus der Klassendefinition, das hat da nichts 
zu suchen!
Persönliche Seite #1700206
Lesenswert?

Die Implementierung heißt main und nicht /DE_handler::main/.

Deswegen funktioniert es, der Compiler erwartet ein main auf globaler 
Ebene.

Hättest Du Deine Implementierung /DE_handler::main/ genannt, würde Dich 
der Linker anmotzen, weil er kein main finden kann.

Würde irgendwo /DE_handler::main/ referenziert, würde der Compiler 
motzen, solange es keine Implementierung davon gibt.

> Ich stolper über viele Sachen in C++, weil ich davor lange in Java
> programmiert habe. Vor allem die ganzen Deklarationen und die
> Headerdateien verwirren mich.

Das ist der Vorteil von Java, daß es mit C++ nur die Syntax, sonst 
aber nicht viel gemein hat.
#1700209
Lesenswert?

Maxim schrieb:

> Ich stolper über viele Sachen in C++, weil ich davor lange in Java
> programmiert habe.

Du stolperst über viele Sachen in C++, weil du versuchst nach der 
Methode 'Versuch und Irrtum' bzw. 'Für einen alten Java Hasen kann das 
doch nicht so schwer sein' an die Sache ran zu gehen.

Hol dir einen Stroustroup aus der nächsten Buchhandlung und arbeite ihn 
von vorne weg durch. Die ersten Kapitel, wo es um Zahlen, Darstellungen 
und dergleichen geht, kannst du oberflächlich überfliegen. Sobald aber 
die ersten Programme im Text auftauchen, solltest du etwas genauer 
lesen. Du wirst vieles entdecken, was ganz ähnlich wie in Java 
funktioniert. Du wirst aber auch noch viel mehr entdecken, was in C++ 
völlig anders gemacht wird.

Zb. Muss in Java jede Funktion ein Member einer Klasse sein.
In C++ aber nicht. Es ist kein Problem freistehende Funktionen zu haben, 
die zu keiner Klasse gehören.

Ganz im Gegenteil: 1 Funktion ist in jedem Programm, welche zu keiner 
Klasse gehört: main()

Und deine static Funktionen:
Diese Funktionen haben ja im eigentlichen Sinn überhaupt nichts mit 
einem DE_Handler zu tun (was immer das auch sein mag). An dieser Stelle 
macht diese Klasse überhaupt keien Sinn! Es sieht so aus, dass du die 
Klasse nur deswegen gebaut hast, weil du von Java gewohnt bist, dass 
jede Funktion in irgendeiner Klasse sein muss.
Aber wie schon gesagt: In C++ ist das nicht so. Man gruppiert Funktionen 
in Klassen, weil es sinnvoll ist, weil diese Funktionen einen 
gemeinsamen Bezug zueinander und zur Klasse haben und nicht weil das 
Sprachkonzept es nicht erlaubt Funktionen ausserhalb von Klassen zu 
haben.

Und wenn du dann im Stroustroup soweit vorgedrungen bist, sollte man 
sich auch einmal über Argument Passing Mechanismen unterhalten :-)
Gast #1701371
Lesenswert?

Maxim schrieb:

> Mit static hatte der Compiler dann auch Probleme. Anscheinend darf
> static vor der Methode nur in der Headerdatei stehen, nicht aber im
> Quellcode, oder?

Richtig. Das ist etwas seltsam, aber ist nun mal so in C++.

Du solltest dir auch mal die Standardlib anschauen. Für das, was du da 
mit vector<float> machst, wäre std::valarray<float> eine sinnvolle 
Alternative. Da ist das, was deine Funktionen machen, schon als 
Operatoren vordefiniert.
Damit könnten die Funktionen so aussehen:
1
valarray<float> mul_vec(valarray<float> arr, float k)
2
{
3
  arr *= k;
4
  return arr;
5
}
6

7
valarray<float> add_vec(const valarray<float>& arr1, const valarray<float>& arr2)
8
{
9
  return arr1 + arr2;
10
}

Eigentlich braucht man sie also gar nicht mehr.

Übrigens:
1
   vector<vector<float>> results; //calculated results
geht nicht durch einen konformen Compiler. Es müßte heißen:
1
   vector<vector<float> > results; //calculated results

Und warum benutzt du eigentlich überall float statt double? Wenn deine 
Arrays nicht gerade so riesig werden, daß du auf den Speicher achten 
mußt, solltest du grundsätzlich double bevorzugen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren