简体   繁体   中英

How can I have two classes linked each other by a vector (map, multimap..) in C++?

I have two class with a vector that holds instances of a third class.

Basically I have three classes:

  • Corporation
  • Market
  • Equities

Corporation and market can have 0..* equities and equities must be linked to 1 market and 1 corporation (to print values, etc...)

I don't know how to do that properly. For me the problem is when I do one vector of equities in market and coporation, I can't put a link in Equities for Corporation and Market because when the Equities.h is the first it don't know Market and Corporation class found in Equities class. And if Corporation.h and Market.h are the first it say me than it don't know the Equities class found in Corporation and Market class.

What is the best code to build the solution for this? I can't say to VisualStudio to go away when he see a class than it never see already? (because the definition is just to the next so it change nothing... :( ) It's impossible in C++ to have in the first class: a link or a vectorof the second class and in the second class: a link or a vector of the first class without having a problem when we build the solution?

Edit:

It's work, I wrote "class Equities; class Corporation; class Market;" and it didn't care about the fact that it didn't know these classes. Thank to everyone it was so quick. I will read your link when I will finish my job: :)

The simplest way is to forward declare or prototype all the classes and types in a common header, place guards on that, and include the header from all your code files. For example:

header.hpp:

#ifndef COMMON_HPP
#define COMMON_HPP

class Corporation;
class Market;
class Equities;

typedef std::shared_ptr<Corporation> CorpRef;

typedef std::list<CorpRef> CorpList;

#endif /*COMMON_HPP*/

body.cpp:

#include header.hpp

class Corporation
{
    static CorpRef Create();
};

and so on.

If you're using Visual Studio exclusively, you can use #pragma once in place of the #ifndef guards.

You are looking for include guards and forward declarations . So, you could just put class Market; in the place where Market is not defined yet.

What are u looking for is term circular dependency look here: http://en.wikipedia.org/wiki/Circular_dependency

So, you could just put class Market; line in place where Market isn't defined yet.

How about:

struct Corporation {
     vector <class Equity *> equities;
}

struct Market {
     vector <class Equity *> equities;
};

struct Equity {
     Market * market;
     Corporation * corp;
};

"peachykeen" option may be the optimal, but, another option, that may help you, in case you use inheritance or subclassing your entities could be:


declarations.h


// these classes doesn't have references to each others

public class FinantialBaseClass
{
  // ...
}

public class CorporationBaseClass: FinantialBaseClass
{
  // ...
}

public class MarketBaseClass: FinantialBaseClass
{
  // ...
}

public class EquitiesBaseClass: FinantialBaseClass
{
  // ...
}


FinantialApp.h


// these classes have references, but, to parent classes,
// not each others

public class CorporationClass: CorporationBaseClass
{
  vector<EquitiesBaseClass> Equities;
}

public class MarketClass: MarketBaseClass
{
  vector<EquitiesBaseClass> Equities;
}

public class EquitiesClass: EquitiesBaseClass
{
  public CorporationBaseClass* Corporation;

  public MarketBaseClass* Market;

}

public class MyFinantialAppClass
{
  protected vector<CorporationBaseClass> Corporations;

  protected vector<MarketBaseClass> Markets;

  protected vector<EquitiesBaseClass> Equities;

  public CorporationBaseClass* addCorporation() { ... }

  public MarketBaseClass* addMarket() { ... }

  public EquitiesBaseClass* addEquity(CorporationBaseClass, MarketBaseClass)
   { ... }

}     

Note that the working classes, each one of them as a "base class", and the working classes reference each others base class, not the class itself. That helps you avoid the circular / forward stuff, that its difficult to use.

Note, that there is an app. class that serves as a container for main classes, and association classes ("equity").

Check that the "equity" class represents an association between a "Market" and a "Corporation". That class is NOT part of the "Market" and a "Corporation", but a component of the "App". If you want to add any class, you do it thru the container, not a to the list of classes themselves.

Note, as an additional, that there is an additional "finantial root base class", that may help you with stuff shared with all classes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM