Порядок, в котором связаны библиотеки, имеет значение, если библиотеки зависят друг от друга. В общем случае, если библиотека A
зависит от библиотеки B
, тогда libA
ДОЛЖЕН появляться перед libB
в флагах компоновщика.
Например:
// B.h
#ifndef B_H
#define B_H
struct B {
B(int);
int x;
};
#endif
// B.cpp
#include "B.h"
B::B(int xx) : x(xx) {}
// A.h
#include "B.h"
struct A {
A(int x);
B b;
};
// A.cpp
#include "A.h"
A::A(int x) : b(x) {}
// main.cpp
#include "A.h"
int main() {
A a(5);
return 0;
};
Создайте библиотеки:
$ g++ -c A.cpp
$ g++ -c B.cpp
$ ar rvs libA.a A.o
ar: creating libA.a
a - A.o
$ ar rvs libB.a B.o
ar: creating libB.a
a - B.o
Скомпилируйте:
$ g++ main.cpp -L. -lB -lA
./libA.a(A.o): In function `A::A(int)':
A.cpp:(.text+0x1c): undefined reference to `B::B(int)'
collect2: error: ld returned 1 exit status
$ g++ main.cpp -L. -lA -lB
$ ./a.out
Чтобы повторить снова, порядок имеет значение!
Маршруты атрибутов не могут быть унаследованы. Это было преднамеренное дизайнерское решение. Мы не чувствовали себя правильно и не видели реальных сценариев, где было бы разумно наследовать их.
Не могли бы вы дать более реалистичный сценарий относительно того, где вы хотели бы использовать это?
[Обновление (3/24/2014)] В предстоящей версии 5.2 MVC Web API , там будет точка расширяемости, называемая System.Web.Http.Routing.IDirectRouteProvider
, через которую вы можете включить сценарий наследования, который вы ищете здесь. Вы можете попробовать это самостоятельно, используя последние ночные сборки (документация о том, как использовать ночные сборки, здесь здесь )
[Обновление (7/31/2014)] Пример того, как это можно сделать сделать в версии Web API 2.2
:
config.MapHttpAttributeRoutes(new CustomDirectRouteProvider());
//---------
public class CustomDirectRouteProvider : DefaultDirectRouteProvider
{
protected override IReadOnlyList<IDirectRouteFactory>
GetActionRouteFactories(HttpActionDescriptor actionDescriptor)
{
// inherit route attributes decorated on base class controller's actions
return actionDescriptor.GetCustomAttributes<IDirectRouteFactory>
(inherit: true);
}
}
Используя Web API 2.2, вы можете:
public class BaseController : ApiController
{
[Route("{id:int}")]
public string Get(int id)
{
return "Success:" + id;
}
}
[RoutePrefix("api/values")]
public class ValuesController : BaseController
{
}
config.MapHttpAttributeRoutes(new CustomDirectRouteProvider());
public class CustomDirectRouteProvider : DefaultDirectRouteProvider
{
protected override IReadOnlyList<IDirectRouteFactory>
GetActionRouteFactories(HttpActionDescriptor actionDescriptor)
{
return actionDescriptor.GetCustomAttributes<IDirectRouteFactory>
(inherit: true);
}
}
, как описано здесь: http://www.asp.net/web-api/overview/releases/whats-new- в-САШ-веб-апи-22
Получил это.
[Route("api/baseuploader/{action}")]
public abstract class BaseUploaderController : ApiController
{
[HttpGet]
public string UploadFile()
{
return "UploadFile";
}
}
[Route("api/values/{action}")]
public class ValuesController : BaseUploaderController
{
[HttpGet]
public string Get(int id)
{
return "value";
}
}
Одно из предостережений здесь состоит в том, что параметр действия маршрута должен быть таким же, как имя действия. Я не мог найти способ обойти это. (Вы не можете переименовать маршрут с помощью атрибута RouteAttribute)