मैं सी ++ में नौसिखिया हूं लेकिन मुझे जावा का उपयोग करने का कुछ अनुभव है। मुझे कुछ त्रुटियां मिल रही हैं जो मुझे समझ में नहीं आ रही हैं। मैंने त्रुटि कंसोल और उसके नीचे दिए गए कोड का एक चित्र संलग्न किया।

 Error  1   error LNK2005: "public: __thiscall VectorDouble::VectorDouble(void)" (??0VectorDouble@@QAE@XZ) already defined in Main.obj  C:\Users\carrea\Code\Visual Studio\COMP201\Lab8_VectorDoubleClass\VectorDouble.obj  Lab8_VectorDoubleClass

 Error  2   error LNK2005: "public: __thiscall VectorDouble::VectorDouble(int)" (??0VectorDouble@@QAE@H@Z) already defined in Main.obj  C:\Users\carrea\Code\Visual Studio\COMP201\Lab8_VectorDoubleClass\VectorDouble.obj  Lab8_VectorDoubleClass
....    

इस तरह की 10 और त्रुटियां और

 Error  13  error LNK1169: one or more multiply defined symbols found   C:\Users\carrea\Code\Visual Studio\COMP201\Lab8_VectorDoubleClass\Debug\Lab8_VectorDoubleClass.exe  1   1   Lab8_VectorDoubleClass

मुख्य.सीपीपी


#include "VectorDouble.cpp"
using namespace std;
void printVD(const VectorDouble& v);
int main()
{
    VectorDouble p;
    p.push_back(1);
    p.push_back(4);
    p.push_back(3);
    VectorDouble v(p);
    printVD(v);
    printVD(p);
}
void printVD(const VectorDouble& v)
{
    int n = v.size();
    for(int i = 0; i<n; i++)
    {
        cout << v.getElementAt(n) << " ";
    }
    cout << endl;
}

वेक्टरडबल.एच


#pragma once
#include <fstream>
#include <iostream>
#include <string>
#include <cstdlib>
#include <iomanip>
#include <vector>
#include <sstream>
using namespace std;
class VectorDouble
{
public:
    VectorDouble(void);
    ~VectorDouble(void);
    VectorDouble(int intSize);
    // Copy constructor
    VectorDouble(const VectorDouble& vd);
    // = override
    void operator =(const VectorDouble& RIGHT_SIDE);
private:
    double *dArray;
    int count, max_count;
public:
    // returns number of occupied cells
    int size(void) const;
    // Returns total number of cells
    int capacity(void) const;
    // Adds an element to array
    void push_back(double num);
    // Resizes the array to be double the original max_count
    void resize(void);
    // Returns element at specified index
    double getElementAt(int i) const;
    // Requests that the capacity of the allocated storage space for the elements of the vector container be at least enough to hold n elements
    void reserve(int n);
private:
    // Sets every element to 0
    void clear(void);
};

वेक्टरडबल.सीपीपी


    #pragma once
#include "VectorDouble.h"

using namespace std;

VectorDouble::VectorDouble(void)
{
    max_count = 100;
    count = 0;
    dArray = new double[max_count];
    clear();
}

VectorDouble::VectorDouble(int intSize)
{
    max_count = intSize;
    dArray = new double[max_count];
    clear();
}

VectorDouble::~VectorDouble(void)
{
    cout << "vector with " << this->count << " is destroyed";
}

// Copy constructor
VectorDouble::VectorDouble(const VectorDouble& vd) 
{
    int mcVD = vd.capacity(), i=0;
    max_count = mcVD;
    dArray = new double[max_count];
    clear();
    while(i<max_count)
    {
        dArray[i] = vd.getElementAt(i);
        i++;
    }
}
// = override
void VectorDouble::operator =(const VectorDouble& RIGHT_SIDE)
{
    int rightCount = RIGHT_SIDE.size(), i=0;
    while(rightCount>max_count)
    {
        resize();
    }
    while(i<rightCount)
    {
        dArray[i] = RIGHT_SIDE.getElementAt(i);
        i++;
    }
    count = i;
}
// returns number of occupied cells
int VectorDouble::size(void) const
{
    return count;
}
// Returns total number of cells
int VectorDouble::capacity(void) const
{
    return max_count;
}
// Adds an element to array
void VectorDouble::push_back(double num)
{
    if(count==max_count)
    {
        resize();
    }
    dArray[count] = num;
    count++;
}
// Resizes the array to be double the original max_count
void VectorDouble::resize(void)
{
    double *p = new double[max_count*2];
    for(int i = 0; i < count; i++)
    {
        p[i] = dArray[i];
    }
    dArray = p;
    max_count*=2;
    delete p;
}


// Returns element at specified index
double VectorDouble::getElementAt(int i) const
{
    return dArray[i];
}


// Requests that the capacity of the allocated storage space for the elements of the vector container be at least enough to hold n elements
void VectorDouble::reserve(int n)
{
    while(n<max_count)
        resize();
}


// Sets every element to 0
void VectorDouble::clear(void)
{
    for(int i = 0; i < max_count; i++)
        dArray[i] = 0;
}

कोई भी सहायताकाफी प्रशंसनीय होगी...

8
SomethingsGottaGive 17 मार्च 2011, 03:17

4 जवाब

सबसे बढ़िया उत्तर

आपको "VectorDouble.h" को शामिल करना चाहिए न कि "VectorDouble.cpp" को Main.cpp में।

फाइलों को शामिल करने की पूरी अवधारणा कई अन्य भाषाओं की तुलना में सी ++ में टूटा हुआ है।

पहला सी ++ चीजों को 'घोषणाओं' और 'परिभाषाओं' में विभाजित करता है। आपके पास कभी भी किसी प्रोग्राम में किसी चीज़ की केवल एक परिभाषा हो सकती है, लेकिन जितनी चाहें उतनी घोषणाएँ। अपनी VectorDouble.cpp फाइल में आप चीजों को परिभाषित कर रहे हैं, और VectorDouble.h फाइल में आप चीजों की घोषणा कर रहे हैं।

C++ में #include निर्देश मृत सरल और बेवकूफी भरा है। जब इसका सामना किया जाता है तो संकलक प्रभावी रूप से एक साधारण पाठ्य प्रतिस्थापन करता है। #include निर्देश को आपके द्वारा शामिल की जा रही फ़ाइल की सामग्री से बदल दिया गया है।

जब आप #include परिभाषाओं की एक फाइल करते हैं, तो इसका मतलब है कि आप उन सभी को प्रभावी ढंग से परिभाषित करते हैं जहां आपने #include किया है। इसलिए आपको "VectorDouble.cpp" को शामिल नहीं करना चाहिए। चूँकि आप उस फ़ाइल को एक अलग फ़ाइल के रूप में संकलित करने की संभावना रखते हैं, फिर आप सभी परिभाषाओं की कम से कम दो प्रतियाँ वहीं पर समाप्त कर देते हैं।

कुछ प्रकार की चीजों के बारे में बात करते समय यह पूरी घोषणा बनाम परिभाषा द्वंद्ववाद बहुत भ्रमित हो जाता है। उदाहरण के लिए, यदि कोई फ़ंक्शन inline घोषित किया जाता है, तो फ़ंक्शन बॉडी को वास्तव में अब definition नहीं माना जाता है। इसका मतलब है कि आपके पास एक फ़ंक्शन बॉडी की जितनी चाहें उतनी प्रतियां हो सकती हैं जिन्हें inline घोषित किया गया है। केवल इतना आवश्यक है कि सभी परिभाषाएँ समान हों।

इसी तरह, एक टेम्पलेट फ़ंक्शन घोषित करना एक घोषणा है, भले ही आप एक फ़ंक्शन बॉडी शामिल करें। ऐसा इसलिए है क्योंकि घोषणा के परिणामस्वरूप कोई कोड उत्पन्न नहीं होता है, केवल टेम्पलेट तत्काल परिणाम कोड पीढ़ी में होता है। और यह तय करने के लिए असली लिटमस टेस्ट है कि कुछ घोषणा या परिभाषा है या नहीं। यदि इसके परिणामस्वरूप स्थान आवंटित किया जा रहा है या वास्तविक कोड वहीं और वहां उत्पादित किया जा रहा है, तो यह एक परिभाषा है, अन्यथा यह एक घोषणा है।

32
Omnifarious 17 मार्च 2011, 03:31

आपको जो त्रुटि मिल रही है वह एक लिंकर त्रुटि है जो आपको बता रही है कि संकलक कुछ सदस्य कार्यों के लिए एकाधिक परिभाषा ढूंढ रहा है। यदि आप त्रुटि संदेश के इस भाग को देखते हैं:

public: __thiscall VectorDouble::VectorDouble(void)" (??0VectorDouble@@QAE@XZ) already defined in Main.obj

आप वहां दबे हुए इस तथ्य को देख सकते हैं कि यह कंस्ट्रक्टर VectorDouble::VectorDouble() के बारे में पहले से ही परिभाषित होने की बात कर रहा है।

मुझे लगता है कि आप जिस विशेष समस्या का सामना कर रहे हैं वह इस पंक्ति में main.cpp में है:

#include "VectorDouble.cpp"

समस्या यह है कि इसमें स्रोत फ़ाइल शामिल है, न कि शीर्षलेख फ़ाइल। नतीजतन, जब आप main.cpp संकलित करते हैं, तो आप सभी मुख्य, साथ ही सभी परिभाषाओं को VectorDouble.cpp में संकलित करेंगे। जब लिंकर इसे वेक्टरडबल.सीपीपी संकलित करते समय उत्पन्न ऑब्जेक्ट फ़ाइल से जोड़ने का प्रयास करता है, तो उसे हर चीज की दो परिभाषाएं मिलेंगी - एक वेक्टरडबल.सीपीपी से और एक मेन.सीपीपी से।

इसे ठीक करने के लिए, इस लाइन को पढ़ने के लिए बदलें

#include "VectorDouble.h"

इससे आपकी समस्या का समाधान होना चाहिए। आम तौर पर, हालांकि, यह वास्तव में #include .cpp फ़ाइल के लिए अत्यंत दुर्लभ है। आप लगभग हमेशा हेडर शामिल करते हैं, स्रोत नहीं।

उम्मीद है ये मदद करेगा!

7
templatetypedef 17 मार्च 2011, 03:22

Main.cpp #include-वेक्टरDouble.cpp नहीं होना चाहिए; इसे #include वेक्टरडबल.एच. यदि आप दोनों .cpp फ़ाइलों को लिंक कर रहे हैं, तो लिंकर सब कुछ वेक्टरडबल.सीपीपी में दो बार देख रहा है (एक बार अपने आप, और एक बार जब यह #include -d Main.cpp से)।

2
dfan 17 मार्च 2011, 03:22

जब मैंने PresentDataStruct.h नामक एक अलग फ़ाइल में एक वर्ग को परिभाषित करने का प्रयास किया और एक PresentDataStruct.cpp फ़ाइल भी बनाई तो मुझे एक समान लिंक त्रुटि मिली।

यहां PresentDataStruct.h की सामग्री दी गई है:

#pragma once

#include <string>
using namespace System;
ref class CPresentDataStruct
{
public:
    CPresentDataStruct();
    ~CPresentDataStruct();

public:
    void SomeActionOnData();

public:

    System::String^ Name;
    DateTime^ BirthDay;

};

void CPresentDataStruct::SomeActionOnData()
{
    //TO DO here
}

CPresentDataStruct::CPresentDataStruct()
{
}

CPresentDataStruct::~CPresentDataStruct()
{
}

जबकि PresentDataStruct.cpp में इसकी एक लाइन है:

include "PresentDataStruct.h"

फिर जब मैं include "PresentDataStruct.h" जोड़ता हूं तो लिंक त्रुटि दिखाई देती है maindialog.h फ़ाइल में।

इसलिए मैंने इसे PresentDataStruct.cpp फ़ाइल में स्थानांतरित कर दिया और लिंक त्रुटि गायब हो गई:

void CPresentDataStruct::SomeActionOnData()
{
    //TO DO here
}

CPresentDataStruct::CPresentDataStruct()
{
}

CPresentDataStruct::~CPresentDataStruct()
{
}
1
Graham 10 फरवरी 2018, 04:31