Компиляция программы на C ++ выполняется в несколько этапов, как указано в 2.2 (кредиты для Кейта Томпсона для ссылки) :
Превалирование среди правил синтаксиса
- Физические символы исходного файла сопоставляются в соответствии с реализацией в соответствии с базовым набором символов источника (ввод символов новой строки для индикаторов конца строки) при необходимости. [SNIP]
- Каждый экземпляр символа обратной косой черты (\), за которым сразу следует символ новой строки, удаляется, сплайсируя физические исходные строки для формирования логических строк источника. [SNIP]
- Исходный файл разбивается на токены предварительной обработки (2.5) и последовательности символов пробела (включая комментарии). [SNIP]
- Выполнены предпроцессорные директивы, макро-вызовы разворачиваются и выполняются операторные выражения _Pragma. [SNIP]
- Каждый элемент набора символов в символьном литерале или строковый литерал, а также каждая escape-последовательность и универсальное имя-символа в символьном литерале или не- -raw строковый литерал, преобразуется в соответствующий член набора символов выполнения; [SNIP]
- Соединительные маркеры литералов строки объединены.
- Символы пробела, разделяющие токены, уже не являются значимыми. Каждый токен предварительной обработки преобразуется в токен. (2.7). Результирующие маркеры синтаксически и семантически анализируются и переводятся как единица перевода. [SNIP]
- Устанавливаемые единицы перевода и единицы экземпляра объединяются следующим образом: [SNIP]
- Все ссылки на внешние сущности решена. Компоненты библиотеки связаны для удовлетворения внешних ссылок на объекты, не определенные в текущем переводе. Весь такой переводчик выводится в образ программы, который содержит информацию, необходимую для выполнения в среде выполнения. (акцент мой)
[footnote] Реализации должны вести себя так, как если бы эти отдельные фазы происходили, хотя на практике различные фазы могли быть свернуты вместе.
Указанные ошибки возникают на этом последнем этапе компиляции, чаще всего называемом связыванием. Это в основном означает, что вы собрали кучу файлов реализации в объектные файлы или библиотеки, и теперь вы хотите заставить их работать вместе.
Скажите, что вы определили символ
a
вa.cpp
. Теперьb.cpp
объявил этот символ и использовал его. Перед связыванием он просто предполагает, что этот символ был определен где-то , но он пока не заботится о том, где. Фаза связывания отвечает за поиск символа и правильную привязку его кb.cpp
(ну, собственно, к объекту или библиотеке, которая его использует).Если вы используете Microsoft Visual Studio, вы будете см., что проекты генерируют файлы
.lib
. Они содержат таблицу экспортированных символов и таблицу импортированных символов. Импортированные символы разрешены против библиотек, на которые вы ссылаетесь, и экспортированные символы предоставляются для библиотек, которые используют этот.lib
(если есть).Подобные механизмы существуют для других компиляторов / платформ.
Общие сообщения об ошибках:
error LNK2001
,error LNK1120
,error LNK2019
для Microsoft Visual Studio иundefined reference to
symbolName для GCC.Код:
struct X { virtual void foo(); }; struct Y : X { void foo() {} }; struct A { virtual ~A() = 0; }; struct B: A { virtual ~B(){} }; extern int x; void foo(); int main() { x = 0; foo(); Y y; B b; }
генерирует следующие ошибки с GCC:
/home/AbiSfw/ccvvuHoX.o: In function `main': prog.cpp:(.text+0x10): undefined reference to `x' prog.cpp:(.text+0x19): undefined reference to `foo()' prog.cpp:(.text+0x2d): undefined reference to `A::~A()' /home/AbiSfw/ccvvuHoX.o: In function `B::~B()': prog.cpp:(.text._ZN1BD1Ev[B::~B()]+0xb): undefined reference to `A::~A()' /home/AbiSfw/ccvvuHoX.o: In function `B::~B()': prog.cpp:(.text._ZN1BD0Ev[B::~B()]+0x12): undefined reference to `A::~A()' /home/AbiSfw/ccvvuHoX.o:(.rodata._ZTI1Y[typeinfo for Y]+0x8): undefined reference to `typeinfo for X' /home/AbiSfw/ccvvuHoX.o:(.rodata._ZTI1B[typeinfo for B]+0x8): undefined reference to `typeinfo for A' collect2: ld returned 1 exit status
и аналогичные ошибки с Microsoft Visual Studio:
1>test2.obj : error LNK2001: unresolved external symbol "void __cdecl foo(void)" (?foo@@YAXXZ) 1>test2.obj : error LNK2001: unresolved external symbol "int x" (?x@@3HA) 1>test2.obj : error LNK2001: unresolved external symbol "public: virtual __thiscall A::~A(void)" (??1A@@UAE@XZ) 1>test2.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall X::foo(void)" (?foo@X@@UAEXXZ) 1>...\test2.exe : fatal error LNK1120: 4 unresolved externals
. Общие причины включают в себя:
- Не удалось связать с соответствующими библиотеками / объектными файлами или скомпилировать файлы реализации
- Объявленная и неопределенная переменная или функция.
- Общие проблемы с элементами класса
- Реализации шаблонов не отображаются.
- Символы были определены в программе на языке C и использовались в коде C ++.
- Неправильно импортировать / экспортировать методы / классы по модулям / dll. (Спецификация MSVS)
- Зависимость круговой библиотеки
- неопределенная ссылка на `WinMain @ 16 '
- Порядок взаимозависимых библиотек
- Несколько исходных файлов с таким же именем
- Мистификация или отсутствие включения расширение .lib при использовании
#pragma
(Microsoft Visual Studio)- Проблемы с друзьями шаблонов
- Несогласован
UNICODE
определения
Чтобы ответить на мой собственный вопрос спустя 4 года, узнав много. Особенно, что вы не должны использовать jQuery для всего. Я создал простой модуль, который может анализировать / строчить строку запроса. Это облегчает изменение строки запроса.
Вы можете использовать строку запроса следующим образом:
// parse the query string into an object
var q = queryString.parse(location.search);
// set the `row` property
q.rows = 10;
// convert the object to a query string
// and overwrite the existing query string
location.search = queryString.stringify(q);
Я думаю, что вам нужен плагин query .
Например:
window.location.search = jQuery.query.set("rows", 10);
Это будет работать независимо от текущего состояния строк.
Современный подход к этому заключается в использовании родного стандартного URLSearchParams . Для более старых браузеров доступны полиполки
const paramsString = "site.fwx?position=1&archiveid=5000&columns=5&rows=20&sorting=ModifiedTimeAsc"
const searchParams = new URLSearchParams(paramsString);
searchParams.set('rows', 10);
console.log(searchParams.toString()); // return modified string.
Бен Алман имеет хороший jquery querystring / url plugin здесь , который позволяет вам легко манипулировать запросами.
Как запрошено -
Перейти к его тесту Страница здесь
В firebug введите следующее в консоль
jQuery.param.querystring(window.location.href, 'a=3&newValue=100');
Он вернет вам следующую измененную строку url
blockquote>Обратите внимание, что значение querystring для a изменилось с X на 3, и оно добавило новое значение.
Затем вы можете использовать новую строку url, но хотите, например, используя document.location = newUrl или изменить привязку и т. д.
Еще одна вариация ответа Саджоя. Просто изменили имена переменных и amp; добавлена оболочка пространства имен:
window.MyNamespace = window.MyNamespace || {};
window.MyNamespace.Uri = window.MyNamespace.Uri || {};
(function (ns) {
ns.SetQueryStringParameter = function(url, parameterName, parameterValue) {
var otherQueryStringParameters = "";
var urlParts = url.split("?");
var baseUrl = urlParts[0];
var queryString = urlParts[1];
var itemSeparator = "";
if (queryString) {
var queryStringParts = queryString.split("&");
for (var i = 0; i < queryStringParts.length; i++){
if(queryStringParts[i].split('=')[0] != parameterName){
otherQueryStringParameters += itemSeparator + queryStringParts[i];
itemSeparator = "&";
}
}
}
var newQueryStringParameter = itemSeparator + parameterName + "=" + parameterValue;
return baseUrl + "?" + otherQueryStringParameters + newQueryStringParameter;
};
})(window.MyNamespace.Uri);
Теперь используется использование:
var changedUrl = MyNamespace.Uri.SetQueryStringParameter(originalUrl, "CarType", "Ford");
Вот что я делаю. Используя мою функцию editParams (), вы можете добавлять, удалять или изменять любой параметр, а затем использовать встроенную функцию replaceState () для обновления URL-адреса:
window.history.replaceState('object or string', 'Title', 'page.html' + editParams('sorting', ModifiedTimeAsc));
// background functions below:
// add/change/remove URL parameter
// use a value of false to remove parameter
// returns a url-style string
function editParams (key, value) {
key = encodeURI(key);
var params = getSearchParameters();
if (Object.keys(params).length === 0) {
if (value !== false)
return '?' + key + '=' + encodeURI(value);
else
return '';
}
if (value !== false)
params[key] = encodeURI(value);
else
delete params[key];
if (Object.keys(params).length === 0)
return '';
return '?' + $.map(params, function (value, key) {
return key + '=' + value;
}).join('&');
}
// Get object/associative array of URL parameters
function getSearchParameters () {
var prmstr = window.location.search.substr(1);
return prmstr !== null && prmstr !== "" ? transformToAssocArray(prmstr) : {};
}
// convert parameters from url-style string to associative array
function transformToAssocArray (prmstr) {
var params = {},
prmarr = prmstr.split("&");
for (var i = 0; i < prmarr.length; i++) {
var tmparr = prmarr[i].split("=");
params[tmparr[0]] = tmparr[1];
}
return params;
}
Быстрое небольшое решение в чистом js, никаких необходимых плагинов:
function replaceQueryParam(param, newval, search) {
var regex = new RegExp("([?;&])" + param + "[^&;]*[;&]?");
var query = search.replace(regex, "$1").replace(/&$/, '');
return (query.length > 2 ? query + "&" : "?") + (newval ? param + "=" + newval : '');
}
Вызвать это следующим образом:
window.location = '/mypage' + replaceQueryParam('rows', 55, window.location.search)
Или, если вы хотите остаться на одной странице и замените несколько параметров:
var str = window.location.search
str = replaceQueryParam('rows', 55, str)
str = replaceQueryParam('cols', 'no', str)
window.location = window.location.pathname + str
отредактируйте, спасибо Luke: Чтобы полностью удалить параметр, передайте false
или null
значение: replaceQueryParam('rows', false, params)
. Поскольку 0
также является ложным , укажите '0'
.
Я искал то же самое и нашел: https://github.com/medialize/URI.js , что довольно приятно:)
- Обновить
Я нашел лучший пакет: https://www.npmjs.org/package/qs он также имеет дело с массивами в параметрах get.
Мой фрагмент с декодированием / кодированием URI:
function isDefined(object) {
return object !== undefined && object !== null;
}
function isNotEmpty(string) {
return isDefined(string) && string.length > 0;
}
/**
* Update or add the specified URL parameter.
* <p>
* @param {String} name
* @param {String} value
*/
function updateUrlParam(name, value) {
// Get the path and the query
var urlInfo = decodeURI(window.location.href).split('?');
var path = urlInfo[0];
var query = urlInfo[1];
// Build the query
var params = '';
var anchor = null;
if (isNotEmpty(query)) {
var queryInfo = query.split('#');
query = queryInfo[0];
anchor = queryInfo[1];
queryInfo = query.split('&');
for (var i = 0; i < queryInfo.length; ++i) {
if (queryInfo[i].split('=')[0] !== name) {
params += '&' + queryInfo[i];
}
}
} else {
var queryInfo = path.split('#');
query = queryInfo[0];
anchor = queryInfo[1];
if (isNotEmpty(query)) {
path = query;
}
}
query = '?' + name + '=' + value + params;
if (isNotEmpty(anchor)) {
query += '#' + anchor;
}
// Replace the URL
window.history.replaceState('', '', encodeURI(path + query));
}
Будет ли жизнеспособной альтернативой манипуляции с String, чтобы настроить html form
и просто изменить значение элемента rows
?
Итак, с html
, что-то вроде
<form id='myForm' target='site.fwx'>
<input type='hidden' name='position' value='1'/>
<input type='hidden' name='archiveid' value='5000'/>
<input type='hidden' name='columns' value='5'/>
<input type='hidden' name='rows' value='20'/>
<input type='hidden' name='sorting' value='ModifiedTimeAsc'/>
</form>
С помощью следующего JavaScript, чтобы отправить форму
var myForm = document.getElementById('myForm');
myForm.rows.value = yourNewValue;
myForm.submit();
Вероятно, не подходит для всех ситуаций, но может быть приятнее, чем синтаксический анализ строки URL.
вы можете сделать это через обычный JS также
var url = document.URL
var newAdditionalURL = "";
var tempArray = url.split("?");
var baseURL = tempArray[0];
var aditionalURL = tempArray[1];
var temp = "";
if(aditionalURL)
{
var tempArray = aditionalURL.split("&");
for ( var i in tempArray ){
if(tempArray[i].indexOf("rows") == -1){
newAdditionalURL += temp+tempArray[i];
temp = "&";
}
}
}
var rows_txt = temp+"rows=10";
var finalURL = baseURL+"?"+newAdditionalURL+rows_txt;
Здесь я взял ответ Адиля Малика и исправил 3 вопроса, которые я идентифицировал с ним.
/**
* Adds or updates a URL parameter.
*
* @param {string} url the URL to modify
* @param {string} param the name of the parameter
* @param {string} paramVal the new value for the parameter
* @return {string} the updated URL
*/
self.setParameter = function (url, param, paramVal){
// http://stackoverflow.com/a/10997390/2391566
var parts = url.split('?');
var baseUrl = parts[0];
var oldQueryString = parts[1];
var newParameters = [];
if (oldQueryString) {
var oldParameters = oldQueryString.split('&');
for (var i = 0; i < oldParameters.length; i++) {
if(oldParameters[i].split('=')[0] != param) {
newParameters.push(oldParameters[i]);
}
}
}
if (paramVal !== '' && paramVal !== null && typeof paramVal !== 'undefined') {
newParameters.push(param + '=' + encodeURI(paramVal));
}
if (newParameters.length > 0) {
return baseUrl + '?' + newParameters.join('&');
} else {
return baseUrl;
}
}
моя функция поддерживает удаление param
function updateURLParameter(url, param, paramVal, remove = false) {
var newAdditionalURL = '';
var tempArray = url.split('?');
var baseURL = tempArray[0];
var additionalURL = tempArray[1];
var rows_txt = '';
if (additionalURL)
newAdditionalURL = decodeURI(additionalURL) + '&';
if (remove)
newAdditionalURL = newAdditionalURL.replace(param + '=' + paramVal, '');
else
rows_txt = param + '=' + paramVal;
window.history.replaceState('', '', (baseURL + "?" + newAdditionalURL + rows_txt).replace('?&', '?').replace('&&', '&').replace(/\&$/, ''));
}
Я расширил код Sujoy для создания функции.
/**
* http://stackoverflow.com/a/10997390/11236
*/
function updateURLParameter(url, param, paramVal){
var newAdditionalURL = "";
var tempArray = url.split("?");
var baseURL = tempArray[0];
var additionalURL = tempArray[1];
var temp = "";
if (additionalURL) {
tempArray = additionalURL.split("&");
for (var i=0; i<tempArray.length; i++){
if(tempArray[i].split('=')[0] != param){
newAdditionalURL += temp + tempArray[i];
temp = "&";
}
}
}
var rows_txt = temp + "" + param + "=" + paramVal;
return baseURL + "?" + newAdditionalURL + rows_txt;
}
Вызовы функции:
var newURL = updateURLParameter(window.location.href, 'locId', 'newLoc');
newURL = updateURLParameter(newURL, 'resId', 'newResId');
window.history.replaceState('', '', updateURLParameter(window.location.href, "param", "value"));
Обновленная версия, которая также заботится о якорях в URL-адресе ,
function updateURLParameter(url, param, paramVal)
{
var TheAnchor = null;
var newAdditionalURL = "";
var tempArray = url.split("?");
var baseURL = tempArray[0];
var additionalURL = tempArray[1];
var temp = "";
if (additionalURL)
{
var tmpAnchor = additionalURL.split("#");
var TheParams = tmpAnchor[0];
TheAnchor = tmpAnchor[1];
if(TheAnchor)
additionalURL = TheParams;
tempArray = additionalURL.split("&");
for (var i=0; i<tempArray.length; i++)
{
if(tempArray[i].split('=')[0] != param)
{
newAdditionalURL += temp + tempArray[i];
temp = "&";
}
}
}
else
{
var tmpAnchor = baseURL.split("#");
var TheParams = tmpAnchor[0];
TheAnchor = tmpAnchor[1];
if(TheParams)
baseURL = TheParams;
}
if(TheAnchor)
paramVal += "#" + TheAnchor;
var rows_txt = temp + "" + param + "=" + paramVal;
return baseURL + "?" + newAdditionalURL + rows_txt;
}
Вы можете использовать эту мою библиотеку для выполнения задания: https://github.com/Mikhus/jsurl
var url = new Url('site.fwx?position=1&archiveid=5000&columns=5&rows=20&sorting=ModifiedTimeAsc');
url.query.rows = 10;
alert( url);
Я написал небольшую вспомогательную функцию, которая работает с любым выбором. Все, что вам нужно сделать, это добавить класс «redirectOnChange» к любому элементу выбора, и это приведет к перезагрузке страницы с помощью нового / измененного параметра querystring, равного id и значению выбора, например:
<select id="myValue" class="redirectOnChange">
<option value="222">test222</option>
<option value="333">test333</option>
</select>
В приведенном выше примере мы добавили бы «? myValue = 222» или «? myValue = 333» (или используя «& amp;», если существуют другие параметры) и перезагрузите страницу.
jQuery:
$(document).ready(function () {
//Redirect on Change
$(".redirectOnChange").change(function () {
var href = window.location.href.substring(0, window.location.href.indexOf('?'));
var qs = window.location.href.substring(window.location.href.indexOf('?') + 1, window.location.href.length);
var newParam = $(this).attr("id") + '=' + $(this).val();
if (qs.indexOf($(this).attr("id") + '=') == -1) {
if (qs == '') {
qs = '?'
}
else {
qs = qs + '&'
}
qs = qs + newParam;
}
else {
var start = qs.indexOf($(this).attr("id") + "=");
var end = qs.indexOf("&", start);
if (end == -1) {
end = qs.length;
}
var curParam = qs.substring(start, end);
qs = qs.replace(curParam, newParam);
}
window.location.replace(href + '?' + qs);
});
});
Я также написал библиотеку для получения и настройки параметров URL-запроса в JavaScript .
Вот пример его использования.
var url = Qurl.create()
, query
, foo
;
] Получить параметры запроса как объект, по ключу или добавить / изменить / удалить.
// returns { foo: 'bar', baz: 'qux' } for ?foo=bar&baz=qux
query = url.query();
// get the current value of foo
foo = url.query('foo');
// set ?foo=bar&baz=qux
url.query('foo', 'bar');
url.query('baz', 'qux');
// unset foo, leaving ?baz=qux
url.query('foo', false); // unsets foo
Это современный способ сделать, если:
function setGetParam(key,value) {
if (history.pushState) {
var params = new URLSearchParams(window.location.search);
params.set(key, value);
var newUrl = window.location.protocol + "//" + window.location.host + window.location.pathname + '?' + params.toString();
window.history.pushState({path:newUrl},'',newUrl);
}
}
Я знаю, что это старый вопрос. Я добавил функцию выше, чтобы добавить или обновить параметры запроса. Все еще чисто JS-решение.
function addOrUpdateQueryParam(param, newval, search) {
var questionIndex = search.indexOf('?');
if (questionIndex < 0) {
search = search + '?';
search = search + param + '=' + newval;
return search;
}
var regex = new RegExp("([?;&])" + param + "[^&;]*[;&]?");
var query = search.replace(regex, "$1").replace(/&$/, '');
var indexOfEquals = query.indexOf('=');
return (indexOfEquals >= 0 ? query + '&' : query + '') + (newval ? param + '=' + newval : '');
}