アプリ版:「スタンプのみでお礼する」機能のリリースについて

コンパイルしたところ下記のようなエラーが出ます。

RoadDriver.obj : error LNK2019: 未解決の外部シンボル "public: void __thiscall Ro
ad::setWidth(float)" (?setWidth@Road@@QAEXM@Z) が関数 _main で参照されました。
RoadDriver.exe : fatal error LNK1120: 外部参照 1 が未解決です。

今C++でクラスを勉強し始めたところです。
普通クラスにはコンストラクターがあるようですが、よく分かってないので使っていません。使わなくても、今回の場合大丈夫なようですが・・・
幅X長さX厚さで道路の体積をもとめるだけのプログラムなのですが、クラスを使うといきなり詰まりました。
下にソースを簡略化したものを載せます。これをコンパイルしても同じエラーが出ました。


ヘッダファイル(名前はRoad.h)は
class Road
{
public:
void setWidth(float w);

private:
float width;
};

別のCPPファイル(名前はRoad.cpp)に
#include "Road.h"
void Road::setWidth(float w)
{
width = w;
}

メインのソースファイル(名前はRoadDriver.cpp)で
#include <iostream>
#include <string>
#include "Road.h"
using namespace std;

int main()
{
Road road;
float w; // w = width(in feet)

cout <<"Enter the width of the road in feet: ";
cin >> w;
road.setWidth(w);

return 0;
}
です。

main()でユーザーから受け取った数値をクラスで作ったwidthに入れようとしています、それがクラスがちゃんと実装されていないのかうまくいかないようです。教科書とかで調べたりしたのですがどこが間違っているのか・・・分かりません。もし宜しければ回答お願いします。

A 回答 (4件)

コマンドラインの場合は次の通り。



方法1)
cl RoadDriver.cpp Road.cpp
というように、全てのソースを指定する

方法2)
cl /c RoadDriver.cpp
cl /c Road.cpp
と/cを付けると、リンクせずにコンパイルして .objファイルを作り
cl RoadDriver.obj Road.obj
でリンクする。
Visual Studioはこれを自動化してくれる
http://msdn.microsoft.com/ja-jp/library/8we9bhf4 …

方法2-1)
上記をBATファイルにする

方法2-2)
Makfileに依存関係を記述して、nmakeでビルドする
    • good
    • 0
この回答へのお礼

コマンドラインだとそうやってコンパイルするんですか!

試してみると、ちゃんとコンパイルできました。

勉強になりました、ありがとうございます!

お礼日時:2012/09/02 01:53

cppファイルがあるなら普通にプロジェクトに取り込んじゃえばいいと思います。



1. 『空のプロジェクト』を作ります
2. プロジェクトのフォルダにRoadDriver.cpp、Road.h、Road.cppをコピーします
3. メニューバーの『プロジェクト』→『既存項目の追加』でファイル選択画面を出します
4. 3を使って、2のファイルをすべてプロジェクトに追加します
5. ビルドします
    • good
    • 0
この回答へのお礼

プロジェクトに取り込んでみると、できました!!

なんで!?っと思ってたんですがNo2の方のおかげで分かりました。

回答ありがとうございます!

お礼日時:2012/09/01 18:16

VS2010だと


ソリューション
+プロジェクト1
 +source
  +~.cpp
 +header
  +~.h
+プロジェクト2
 +source
  +~.cpp
 +header
  +~.h

という感じになっていませんか?

C/C++では
ソースをコンパイル→.OBJ オブジェクトファイル

必要な.OBJと必要な.LIBをリンク→.exe / .lib / .dll 等

というのがビルドの基本の流れです。VisualStudioを使っていると、ボタン一つでできるので、意識してないかもしれませんが。

このビルドはVisual Studioではプロジェクト単位で行います。
このような手でやる面倒な作業をまとめて面倒みてくれるのが、Visual Studio等です。


で、「Road.cppをコンパイル忘れていた」とあるので
プロジェクト1にRoadDriver.cpp
プロジェクト2にRoad.cpp
が入っているのでは無いですか?

そのために、それぞれ独立してリンクしようとして、足りないものがリンクエラーになっています。

方法は大きく2つ。
(1) RoadDriver.cppと Road.cppを同じソリューションの同じプロジェクトに入れる。
ビルドすると、双方をコンパイル→できたオブジェクトを一つにリンク、というのを自動でやってくれるようになります。

(2) Road.cppのプロジェクトを「スタティックライブラリ」用にする
リンクされると、.libができる。それを、RoadDriverのプロジェクトのリンクの入力に加える
プロジェクトの依存関係を設定して、Road→RoadDriverの順にビルドするようにする。


(1)の方が簡単です。
(2)は、後に別のプログラムで.libだけ使う、という使い方ができます。「C 言語」として教わってきた「printf」などは、本当はこのようにして用意されたライブラリです。

この回答への補足

>ソースをコンパイル→.OBJ オブジェクトファイル

必要な.OBJと必要な.LIBをリンク→.exe / .lib / .dll 等

というのがビルドの基本の流れです。VisualStudioを使っていると、ボタン一つでできるので、意識してないかもしれませんが。


なるほど~!!
だからVCのプロジェクトに取り込むと問題なくコンパイルできたんですね!これまでCPPファイルを2つ以上に分けて書いたことがなくて、方法(2)のようなリンクの仕方は知りませんでした。VCは持ってたんですが最近までツールのCommand Promptしか使ってなかったです。エディターはメモ帳でした。

補足日時:2012/09/01 18:08
    • good
    • 0
この回答へのお礼

補足に書いてしまいましたが解決しました

詳しい回答ありがとうございます!!

お礼日時:2012/09/01 18:19

プロジェクトはどうなってます?


Road.cppとRoadDriver.cppが一つのプロジェクトに入ってますか?
あるいは、Road.cppから作ったRoad.objかRoad.libをリンクするように設定されていますか?

この回答への補足

>あるいは、Road.cppから作ったRoad.objかRoad.libをリンクするように設定されていますか?

リンクするように設定というと同じワーキングフォルダーにファイルを入れておけばいいということでしょうか?


それがRoad.cppをコンパイルし忘れていて、それで今そっちもコンパイルしようとしたのですが同じようなエラーが出てしまいます。これ以上外部ファイルはないし・・・関数の構文は間違ってないと思うし・・・なぜコンパイルできないのでしょうか?
↓がそのエラーです。

/out:Road.exe
Road.obj
LIBCMT.lib(crt0.obj) : error LNK2019: 未解決の外部シンボル _main が関数 ___tmain
CRTStartup で参照されました。
Road.exe : fatal error LNK1120: 外部参照 1 が未解決です。


あと補足ですがコンパイルにはVS 2010を使っています

補足日時:2012/09/01 14:05
    • good
    • 0
この回答へのお礼

おかげ様でリンクの設定の仕方も分かりました。 ありがとうございます!

お礼日時:2012/09/02 02:14

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!