【问题标题】:C++ namespacing to maintain old code用于维护旧代码的 C++ 命名空间
【发布时间】:2018-02-06 19:23:31
【问题描述】:

我正在为一个应用程序编写一个新的 REST 路由器。它有一些旧的 C++ 类,称为 Route 等等。我创建了一些新类,即(你猜对了)RouteRouteManager。在整个应用程序中实际上使用了 0 个命名空间。所以我想通过引入我自己的命名空间 (WebRouter) 来编写代码,同时将旧代码保留在项目中。

显然这不起作用。我的编译器(C++98)抱怨已经定义的东西(Route 和 cout 重载)。这就是我试图实现我的目标的方法,即保留旧的 Route 类,同时命名新的 Route 类。

Route.hpp

namespace WebRouter {
    // complains this is defined, which it is for the old Route..
    class Route {
        private:
        protected:
        public:
            string uri;
            string method;
            Route(string uri, string method);
            ~Route();
    };
}
// complains this is already defined, which it is for the old Route..
ostream &operator<<(std::ostream &os, WebRouter::Route const &route) { 
    os << "--- Route ---" << endl;
    os << "- URI: " << route.uri << endl;
    os << "- Method: " << route.method << endl;
    os << "-------------" << endl;
    return os;
}

Route.cpp

#include "Route.hpp"
using namespace WebRouter;

Route::Route(string uri, string method){
    this->uri = uri;
    this->method = method;
}
Route::~Route(){}

RouteManager.hpp

namespace WebRouter {
    class RouteManager {
        private:
            vector<Route> RouteVector;
        protected:
        public:
            RouteManager();
            ~RouteManager();
            Route* FindRoute(string uri, string method);
    };
}

RouteManager.cpp

#include "RouterManager.hpp"
using namespace WebRouter;

RouteManager::RouteManager() {}
RouteManager::~RouteManager() {}

具体错误是

multiple definition of 'global constructors keyed to 2343_2__zoidfiosdiof**WebRouter**5**Route**E'

无论我使用using 还是前缀WebRouter::,都会发生这种情况

【问题讨论】:

  • using namespace WebRouter; 这就是你的问题。
  • 只是不要偷懒。 using 只会让你拥有 RouterRouter 这实际上是两个不同的东西。 RouterWebRouter::Router 不是更容易区分吗?
  • 如果你去掉using namespace WebRouter 而是在RouteManager.cpp 中的函数前加上WebRouter:: 会发生什么?
  • 对不起朋友,但删除 using 并以 WebRouter:: 为前缀并不能完成任何事情。它仍然向我抱怨multiple definition of 'global constructors keyed to (gibberish text)WebRouter Route
  • 惯用的方法是在 CPP 文件中再次声明命名空间,例如 namespace WebRouter{ Route::Route(...){} Route::~Route(){} }

标签: c++


【解决方案1】:

有几件事应该或必须改变(我们没有你所有的源文件来检查):

  1. 不要使用using namespace WebRouter,因为一些 cmets 指出使用WebRouter:: 是一个更好的策略
  2. 您的 Route 构造函数和析构函数定义也应该放在 cpp 文件中的 WebRouter 命名空间内。
  3. Route 类的输出流重载也可以作为友元进入类范围内并在命名空间内定义。

【讨论】:

  • 去掉重载之后,一切都可以正常编译(即使按照我的原始代码)。但是,如果我将重载放在 Route.hpp 文件中的 WebRouter 命名空间中,它仍然是它唯一抱怨的...
  • 你是否在 Route 类中将函数声明为friend ostream &amp;operator&lt;&lt;(std::ostream &amp;os, WebRouter::Route const &amp;route);
  • 是的。所有这一切都会让我访问私有变量。它仍然认为它被定义了两次。在这一点上,它甚至看起来与旧类没有任何关系。
  • 是的,肯定发生了一些可疑的事情。我将它重命名为 Route2 和同样的问题 =/
  • 肯定是双重定义的。 RouteManager.hpp 包括 Route.hppRoute.cpp 包括 Route.hpp。因此,运算符是双重定义的。我将整个东西移到了类头中,现在它可以工作了。学过的知识。见this answer。也许这就是你的第三点的意思,但我不明白。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-14
  • 1970-01-01
  • 2011-03-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多